Version Description
Download this release
Release Info
Developer | websupporter |
Plugin | Antispam Bee |
Version | 2.9.0 |
Comparing to | |
See all releases |
Code changes from version 2.8.1 to 2.9.0
- antispam_bee.php +1377 -1302
- inc/columns.class.php +64 -79
- inc/gui.class.php +215 -185
- js/raphael.min.js +3 -10
- readme.txt +16 -1
antispam_bee.php
CHANGED
@@ -1,16 +1,18 @@
|
|
1 |
<?php
|
2 |
-
|
3 |
-
* Plugin Name: Antispam Bee
|
4 |
-
* Description: Antispam plugin with a sophisticated toolset for effective day to day comment and trackback spam-fighting. Built with data protection and privacy in mind.
|
5 |
-
* Author: pluginkollektiv
|
6 |
-
* Author URI: https://pluginkollektiv.org
|
7 |
-
* Plugin URI: https://wordpress.org/plugins/antispam-bee/
|
8 |
-
* Text Domain: antispam-bee
|
9 |
-
* Domain Path: /lang
|
10 |
-
* License: GPLv2 or later
|
11 |
-
* License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
12 |
-
* Version: 2.
|
13 |
-
|
|
|
|
|
14 |
|
15 |
/*
|
16 |
* Copyright (C) 2009-2015 Sergej Müller
|
@@ -34,229 +36,251 @@
|
|
34 |
// Make sure this file is only run from within the WordPress context.
|
35 |
defined( 'ABSPATH' ) || exit;
|
36 |
|
37 |
-
|
38 |
/**
|
39 |
-
* Antispam_Bee
|
40 |
-
*
|
41 |
-
* @since 0.1
|
42 |
-
* @change 2.4
|
43 |
-
*/
|
44 |
-
|
45 |
class Antispam_Bee {
|
46 |
|
47 |
-
|
48 |
-
|
|
|
|
|
|
|
49 |
public static $defaults;
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
private static $_base;
|
|
|
|
|
|
|
|
|
|
|
|
|
51 |
private static $_salt;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
private static $_reason;
|
53 |
-
private static $_current_post_id;
|
54 |
|
|
|
|
|
|
|
|
|
|
|
|
|
55 |
|
56 |
/**
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
62 |
|
63 |
-
|
64 |
-
{
|
65 |
-
// Delete spam reason
|
66 |
-
add_action(
|
67 |
-
'unspam_comment',
|
68 |
-
array(
|
69 |
-
__CLASS__,
|
70 |
-
'delete_spam_reason_by_comment'
|
71 |
-
)
|
72 |
-
);
|
73 |
-
|
74 |
-
// AJAX & Co.
|
75 |
-
if ( (defined('DOING_AJAX') && DOING_AJAX) or (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) ) {
|
76 |
return;
|
77 |
}
|
78 |
|
79 |
-
// Initialization
|
80 |
self::_init_internal_vars();
|
81 |
|
82 |
-
|
83 |
-
if ( defined('DOING_CRON') ) {
|
84 |
add_action(
|
85 |
'antispam_bee_daily_cronjob',
|
86 |
array(
|
87 |
__CLASS__,
|
88 |
-
'start_daily_cronjob'
|
89 |
)
|
90 |
);
|
91 |
|
92 |
-
// Admin
|
93 |
} elseif ( is_admin() ) {
|
94 |
-
// Menu
|
95 |
add_action(
|
96 |
'admin_menu',
|
97 |
array(
|
98 |
__CLASS__,
|
99 |
-
'add_sidebar_menu'
|
100 |
)
|
101 |
);
|
102 |
|
103 |
-
|
104 |
-
if ( self::_current_page('dashboard') ) {
|
105 |
add_action(
|
106 |
'init',
|
107 |
array(
|
108 |
__CLASS__,
|
109 |
-
'load_plugin_lang'
|
110 |
)
|
111 |
);
|
112 |
add_filter(
|
113 |
'dashboard_glance_items',
|
114 |
array(
|
115 |
__CLASS__,
|
116 |
-
'add_dashboard_count'
|
117 |
)
|
118 |
);
|
119 |
add_action(
|
120 |
'wp_dashboard_setup',
|
121 |
array(
|
122 |
__CLASS__,
|
123 |
-
'add_dashboard_chart'
|
124 |
)
|
125 |
);
|
126 |
|
127 |
-
|
128 |
-
} else if ( self::_current_page('plugins') ) {
|
129 |
add_action(
|
130 |
'init',
|
131 |
array(
|
132 |
__CLASS__,
|
133 |
-
'load_plugin_lang'
|
134 |
)
|
135 |
);
|
136 |
add_filter(
|
137 |
'plugin_row_meta',
|
138 |
array(
|
139 |
__CLASS__,
|
140 |
-
'init_row_meta'
|
141 |
),
|
142 |
10,
|
143 |
2
|
144 |
);
|
145 |
add_filter(
|
146 |
-
'plugin_action_links_' .self::$_base,
|
147 |
array(
|
148 |
__CLASS__,
|
149 |
-
'init_action_links'
|
150 |
)
|
151 |
);
|
152 |
|
153 |
-
|
154 |
-
} else if ( self::_current_page('options') ) {
|
155 |
add_action(
|
156 |
'admin_init',
|
157 |
array(
|
158 |
__CLASS__,
|
159 |
-
'load_plugin_lang'
|
160 |
)
|
161 |
);
|
162 |
add_action(
|
163 |
'admin_init',
|
164 |
array(
|
165 |
__CLASS__,
|
166 |
-
'init_plugin_sources'
|
167 |
)
|
168 |
);
|
169 |
|
170 |
-
}
|
171 |
-
require_once
|
172 |
|
173 |
add_action(
|
174 |
'admin_post_ab_save_changes',
|
175 |
array(
|
176 |
'Antispam_Bee_GUI',
|
177 |
-
'save_changes'
|
178 |
)
|
179 |
);
|
180 |
|
181 |
-
}
|
182 |
-
|
183 |
-
|
184 |
-
|
|
|
185 |
|
186 |
-
// Load textdomain
|
187 |
self::load_plugin_lang();
|
188 |
|
189 |
-
// Add plugin columns
|
190 |
add_filter(
|
191 |
'manage_edit-comments_columns',
|
192 |
array(
|
193 |
'Antispam_Bee_Columns',
|
194 |
-
'register_plugin_columns'
|
195 |
)
|
196 |
);
|
197 |
add_filter(
|
198 |
'manage_comments_custom_column',
|
199 |
array(
|
200 |
'Antispam_Bee_Columns',
|
201 |
-
'print_plugin_column'
|
202 |
),
|
203 |
10,
|
204 |
2
|
205 |
);
|
206 |
add_filter(
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
);
|
213 |
|
214 |
add_filter(
|
215 |
'manage_edit-comments_sortable_columns',
|
216 |
array(
|
217 |
'Antispam_Bee_Columns',
|
218 |
-
'register_sortable_columns'
|
219 |
)
|
220 |
);
|
221 |
add_action(
|
222 |
'pre_get_posts',
|
223 |
array(
|
224 |
'Antispam_Bee_Columns',
|
225 |
-
'set_orderby_query'
|
226 |
)
|
227 |
);
|
228 |
}
|
229 |
}
|
230 |
-
|
231 |
-
// Frontend
|
232 |
} else {
|
233 |
add_action(
|
234 |
'wp',
|
235 |
array(
|
236 |
__CLASS__,
|
237 |
-
'populate_post_id'
|
238 |
)
|
239 |
);
|
240 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
241 |
add_action(
|
242 |
'template_redirect',
|
243 |
array(
|
244 |
__CLASS__,
|
245 |
-
'prepare_comment_field'
|
246 |
)
|
247 |
);
|
248 |
add_action(
|
249 |
'init',
|
250 |
array(
|
251 |
__CLASS__,
|
252 |
-
'precheck_incoming_request'
|
253 |
)
|
254 |
);
|
255 |
add_action(
|
256 |
'preprocess_comment',
|
257 |
array(
|
258 |
__CLASS__,
|
259 |
-
'handle_incoming_request'
|
260 |
),
|
261 |
1
|
262 |
);
|
@@ -264,7 +288,7 @@ class Antispam_Bee {
|
|
264 |
'antispam_bee_count',
|
265 |
array(
|
266 |
__CLASS__,
|
267 |
-
'the_spam_count'
|
268 |
)
|
269 |
);
|
270 |
}
|
@@ -272,22 +296,19 @@ class Antispam_Bee {
|
|
272 |
|
273 |
|
274 |
|
275 |
-
/*
|
276 |
-
*
|
277 |
-
*
|
278 |
-
*
|
279 |
-
*/
|
280 |
-
|
281 |
-
/**
|
282 |
-
* Action during the activation of the Plugins
|
283 |
-
*
|
284 |
-
* @since 0.1
|
285 |
-
* @change 2.4
|
286 |
*/
|
287 |
|
288 |
-
|
289 |
-
|
290 |
-
|
|
|
|
|
|
|
|
|
291 |
add_option(
|
292 |
'antispam_bee',
|
293 |
array(),
|
@@ -295,184 +316,176 @@ class Antispam_Bee {
|
|
295 |
'no'
|
296 |
);
|
297 |
|
298 |
-
|
299 |
-
if ( self::get_option('cronjob_enable') ) {
|
300 |
self::init_scheduled_hook();
|
301 |
}
|
302 |
}
|
303 |
|
304 |
|
305 |
/**
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
public static function deactivate()
|
313 |
-
{
|
314 |
self::clear_scheduled_hook();
|
315 |
}
|
316 |
|
317 |
|
318 |
/**
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
global $wpdb;
|
329 |
|
330 |
-
|
331 |
-
|
332 |
|
333 |
-
//
|
334 |
-
$
|
|
|
|
|
335 |
}
|
336 |
|
337 |
|
338 |
|
339 |
-
/*
|
340 |
-
*
|
341 |
-
*
|
342 |
-
*
|
343 |
-
*/
|
344 |
-
|
345 |
-
/**
|
346 |
-
* Initialization of the internal variables
|
347 |
-
*
|
348 |
-
* @since 2.4
|
349 |
-
* @change 2.7.0
|
350 |
*/
|
351 |
|
352 |
-
|
353 |
-
|
354 |
-
|
|
|
|
|
|
|
|
|
|
|
355 |
|
356 |
-
$salt
|
357 |
self::$_salt = substr( sha1( $salt ), 0, 10 );
|
358 |
|
359 |
self::$defaults = array(
|
360 |
'options' => array(
|
361 |
-
|
362 |
-
'
|
363 |
-
'
|
364 |
-
'
|
365 |
-
'
|
366 |
-
'
|
367 |
-
'
|
368 |
-
'
|
369 |
-
|
370 |
-
|
371 |
-
'
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
'
|
376 |
-
|
377 |
-
'
|
378 |
-
|
379 |
-
|
380 |
-
'
|
381 |
-
|
382 |
-
'
|
383 |
-
|
384 |
-
|
385 |
-
'
|
386 |
-
'
|
387 |
-
|
388 |
-
'
|
389 |
-
'
|
390 |
-
|
391 |
-
'
|
392 |
-
'
|
393 |
-
|
394 |
-
'
|
395 |
-
'ignore_reasons' => array(),
|
396 |
),
|
397 |
'reasons' => array(
|
398 |
-
'css'
|
399 |
-
'time'
|
400 |
-
'empty'
|
401 |
-
'server'
|
402 |
-
'localdb'
|
403 |
-
'country'
|
404 |
-
'bbcode'
|
405 |
-
'lang'
|
406 |
-
'regexp'
|
407 |
-
|
|
|
408 |
);
|
409 |
}
|
410 |
|
411 |
-
|
412 |
/**
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
{
|
425 |
-
if ( empty($array) or empty($key) or empty($array[$key]) ) {
|
426 |
return null;
|
427 |
}
|
428 |
|
429 |
-
return $array[$key];
|
430 |
}
|
431 |
|
432 |
|
433 |
/**
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
switch ($page) {
|
446 |
case 'dashboard':
|
447 |
-
return ( empty($GLOBALS['pagenow'])
|
448 |
|
449 |
case 'options':
|
450 |
-
return ( !empty($_GET['page']) && $_GET['page']
|
451 |
|
452 |
case 'plugins':
|
453 |
-
return ( !empty($GLOBALS['pagenow']) && $GLOBALS['pagenow']
|
454 |
|
455 |
case 'admin-post':
|
456 |
-
return ( !empty($GLOBALS['pagenow']) && $GLOBALS['pagenow']
|
457 |
|
458 |
case 'edit-comments':
|
459 |
-
return ( !empty($GLOBALS['pagenow']) && $GLOBALS['pagenow']
|
460 |
|
461 |
default:
|
462 |
return false;
|
463 |
}
|
|
|
464 |
}
|
465 |
|
466 |
|
467 |
/**
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
public static function load_plugin_lang()
|
475 |
-
{
|
476 |
load_plugin_textdomain(
|
477 |
'antispam-bee'
|
478 |
);
|
@@ -480,16 +493,16 @@ class Antispam_Bee {
|
|
480 |
|
481 |
|
482 |
/**
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
if ( ! current_user_can('manage_options') ) {
|
493 |
return $data;
|
494 |
}
|
495 |
|
@@ -500,32 +513,28 @@ class Antispam_Bee {
|
|
500 |
'<a href="%s">%s</a>',
|
501 |
add_query_arg(
|
502 |
array(
|
503 |
-
'page' => 'antispam_bee'
|
504 |
),
|
505 |
-
admin_url('options-general.php')
|
506 |
),
|
507 |
-
esc_attr__('Settings', 'antispam-bee')
|
508 |
-
)
|
509 |
)
|
510 |
);
|
511 |
}
|
512 |
|
513 |
-
|
514 |
/**
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
{
|
527 |
-
// Rights
|
528 |
-
if ( $file != self::$_base ) {
|
529 |
return $input;
|
530 |
}
|
531 |
|
@@ -538,38 +547,31 @@ class Antispam_Bee {
|
|
538 |
);
|
539 |
}
|
540 |
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
*
|
545 |
-
* ####### RESOURCES ########
|
546 |
-
* ############################
|
547 |
-
*/
|
548 |
-
|
549 |
-
/**
|
550 |
-
* Registration of resources (CSS & JS)
|
551 |
-
*
|
552 |
-
* @since 1.6
|
553 |
-
* @change 2.4.5
|
554 |
*/
|
555 |
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
|
|
|
|
|
|
|
|
560 |
|
561 |
-
// Integrate JS
|
562 |
wp_register_script(
|
563 |
'ab_script',
|
564 |
-
plugins_url('js/scripts.min.js', __FILE__),
|
565 |
-
array('jquery'),
|
566 |
$plugin['Version']
|
567 |
);
|
568 |
|
569 |
-
// Integrate CSS
|
570 |
wp_register_style(
|
571 |
'ab_style',
|
572 |
-
plugins_url('css/styles.min.css', __FILE__),
|
573 |
array( 'dashicons' ),
|
574 |
$plugin['Version']
|
575 |
);
|
@@ -577,15 +579,12 @@ class Antispam_Bee {
|
|
577 |
|
578 |
|
579 |
/**
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
|
584 |
-
|
585 |
-
|
586 |
-
public static function add_sidebar_menu()
|
587 |
-
{
|
588 |
-
// Create menu
|
589 |
$page = add_options_page(
|
590 |
'Antispam Bee',
|
591 |
'Antispam Bee',
|
@@ -593,191 +592,165 @@ class Antispam_Bee {
|
|
593 |
'antispam_bee',
|
594 |
array(
|
595 |
'Antispam_Bee_GUI',
|
596 |
-
'options_page'
|
597 |
)
|
598 |
);
|
599 |
|
600 |
-
// Integrate JS
|
601 |
add_action(
|
602 |
'admin_print_scripts-' . $page,
|
603 |
array(
|
604 |
__CLASS__,
|
605 |
-
'add_options_script'
|
606 |
)
|
607 |
);
|
608 |
|
609 |
-
// Integrate CSS
|
610 |
add_action(
|
611 |
'admin_print_styles-' . $page,
|
612 |
array(
|
613 |
__CLASS__,
|
614 |
-
'add_options_style'
|
615 |
)
|
616 |
);
|
617 |
|
618 |
-
// Load PHP
|
619 |
add_action(
|
620 |
-
'load-'
|
621 |
array(
|
622 |
__CLASS__,
|
623 |
-
'init_options_page'
|
624 |
)
|
625 |
);
|
626 |
}
|
627 |
|
628 |
|
629 |
/**
|
630 |
-
|
631 |
-
|
632 |
-
|
633 |
-
|
634 |
-
|
635 |
-
|
636 |
-
|
637 |
-
{
|
638 |
-
wp_enqueue_script('ab_script');
|
639 |
}
|
640 |
|
641 |
|
642 |
/**
|
643 |
-
|
644 |
-
|
645 |
-
|
646 |
-
|
647 |
-
|
648 |
-
|
649 |
-
|
650 |
-
{
|
651 |
-
wp_enqueue_style('ab_style');
|
652 |
}
|
653 |
|
654 |
|
655 |
/**
|
656 |
-
|
657 |
-
|
658 |
-
|
659 |
-
|
660 |
-
|
661 |
-
|
662 |
-
|
663 |
-
{
|
664 |
-
require_once( dirname(__FILE__). '/inc/gui.class.php' );
|
665 |
}
|
666 |
|
667 |
|
668 |
|
669 |
-
/*
|
670 |
-
*
|
671 |
-
*
|
672 |
-
*
|
673 |
-
*/
|
674 |
-
|
675 |
-
/**
|
676 |
-
* Display the spam counter on the dashboard
|
677 |
-
*
|
678 |
-
* @since 0.1
|
679 |
-
* @change 2.6.5
|
680 |
-
*
|
681 |
-
* @param array $items Initial array with dashboard items
|
682 |
-
* @return array $items Merged array with dashboard items
|
683 |
*/
|
684 |
|
685 |
-
|
686 |
-
|
687 |
-
|
688 |
-
|
689 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
690 |
}
|
691 |
|
692 |
-
|
693 |
-
echo '<style>#dashboard_right_now .ab-count:before {content: "\f117"}</style>';
|
694 |
|
695 |
-
|
696 |
-
|
697 |
-
|
698 |
-
|
699 |
-
)
|
|
|
700 |
) . '</span>';
|
701 |
|
702 |
-
|
703 |
}
|
704 |
|
705 |
-
|
706 |
/**
|
707 |
-
|
708 |
-
|
709 |
-
|
710 |
-
|
711 |
-
|
712 |
-
public static function add_dashboard_chart()
|
713 |
-
{
|
714 |
-
// Filter
|
715 |
if ( ! current_user_can( 'publish_posts' ) || ! self::get_option( 'dashboard_chart' ) ) {
|
716 |
return;
|
717 |
}
|
718 |
|
719 |
-
// Add Widget
|
720 |
wp_add_dashboard_widget(
|
721 |
'ab_widget',
|
722 |
'Antispam Bee',
|
723 |
array(
|
724 |
__CLASS__,
|
725 |
-
'show_spam_chart'
|
726 |
)
|
727 |
);
|
728 |
|
729 |
-
// Load CSS
|
730 |
add_action(
|
731 |
'admin_head',
|
732 |
array(
|
733 |
__CLASS__,
|
734 |
-
'add_dashboard_style'
|
735 |
)
|
736 |
);
|
737 |
}
|
738 |
|
739 |
-
|
740 |
/**
|
741 |
-
|
742 |
-
|
743 |
-
|
744 |
-
|
745 |
-
|
746 |
-
|
747 |
-
|
748 |
-
{
|
749 |
-
// Get plugin data
|
750 |
-
$plugin = get_plugin_data(__FILE__);
|
751 |
|
752 |
-
// Register styles
|
753 |
wp_register_style(
|
754 |
'ab_chart',
|
755 |
-
plugins_url('css/dashboard.min.css', __FILE__),
|
756 |
array(),
|
757 |
$plugin['Version']
|
758 |
);
|
759 |
|
760 |
-
|
761 |
-
wp_print_styles('ab_chart');
|
762 |
}
|
763 |
|
764 |
|
765 |
/**
|
766 |
-
|
767 |
-
|
768 |
-
|
769 |
-
|
770 |
-
|
771 |
public static function add_dashboard_script() {
|
772 |
-
|
773 |
-
if ( ! self::get_option('daily_stats') ) {
|
774 |
return;
|
775 |
}
|
776 |
|
777 |
-
|
778 |
-
$plugin = get_plugin_data(__FILE__);
|
779 |
|
780 |
-
// Embed scripts
|
781 |
wp_enqueue_script(
|
782 |
'raphael',
|
783 |
plugins_url( 'js/raphael.min.js', __FILE__ ),
|
@@ -803,84 +776,67 @@ class Antispam_Bee {
|
|
803 |
);
|
804 |
}
|
805 |
|
806 |
-
|
807 |
/**
|
808 |
-
|
809 |
-
|
810 |
-
|
811 |
-
|
812 |
-
|
813 |
-
|
814 |
-
|
815 |
-
{
|
816 |
-
// Get stats
|
817 |
-
$items = (array)self::get_option('daily_stats');
|
818 |
|
819 |
-
|
820 |
-
if ( empty($items) ) {
|
821 |
echo sprintf(
|
822 |
'<div id="ab_chart"><p>%s</p></div>',
|
823 |
-
esc_html__('No data available.', 'antispam-bee')
|
824 |
);
|
825 |
|
826 |
return;
|
827 |
}
|
828 |
|
829 |
-
// Enqueue scripts.
|
830 |
self::add_dashboard_script();
|
831 |
|
832 |
-
|
833 |
-
ksort($items, SORT_NUMERIC);
|
834 |
|
835 |
-
// Start HTML
|
836 |
$html = "<table id=ab_chart_data>\n";
|
837 |
|
838 |
-
|
839 |
-
// Timestamp table
|
840 |
$html .= "<tfoot><tr>\n";
|
841 |
-
foreach($items as $date => $count) {
|
842 |
-
$html .=
|
843 |
}
|
844 |
$html .= "</tr></tfoot>\n";
|
845 |
|
846 |
-
// Counter table
|
847 |
$html .= "<tbody><tr>\n";
|
848 |
-
foreach($items as $date => $count) {
|
849 |
-
$html .=
|
850 |
}
|
851 |
$html .= "</tr></tbody>\n";
|
852 |
|
853 |
-
|
854 |
-
// HTML end
|
855 |
$html .= "</table>\n";
|
856 |
|
857 |
-
|
858 |
-
echo '<div id="ab_chart">' .$html. '</div>';
|
859 |
}
|
860 |
|
861 |
-
|
862 |
-
|
863 |
-
|
864 |
-
*
|
865 |
-
* ######## OPTIONS #########
|
866 |
-
* ############################
|
867 |
-
*/
|
868 |
-
|
869 |
-
/**
|
870 |
-
* Get all plugin options
|
871 |
-
*
|
872 |
-
* @since 2.4
|
873 |
-
* @change 2.6.1
|
874 |
-
*
|
875 |
-
* @return array $options Array with option fields
|
876 |
*/
|
877 |
|
878 |
-
|
879 |
-
|
880 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
881 |
wp_cache_set(
|
882 |
'antispam_bee',
|
883 |
-
$options = get_option('antispam_bee')
|
884 |
);
|
885 |
}
|
886 |
|
@@ -890,78 +846,65 @@ class Antispam_Bee {
|
|
890 |
);
|
891 |
}
|
892 |
|
893 |
-
|
894 |
/**
|
895 |
-
|
896 |
-
|
897 |
-
|
898 |
-
|
899 |
-
|
900 |
-
|
901 |
-
|
902 |
-
|
903 |
-
|
904 |
-
public static function get_option($field)
|
905 |
-
{
|
906 |
-
// Get all options
|
907 |
$options = self::get_options();
|
908 |
|
909 |
-
return self::get_key($options, $field);
|
910 |
}
|
911 |
|
912 |
|
913 |
/**
|
914 |
-
|
915 |
-
|
916 |
-
|
917 |
-
|
918 |
-
|
919 |
-
|
920 |
-
|
921 |
-
|
922 |
-
|
923 |
-
private static function _update_option($field, $value)
|
924 |
-
{
|
925 |
self::update_options(
|
926 |
array(
|
927 |
-
$field => $value
|
928 |
)
|
929 |
);
|
930 |
}
|
931 |
|
932 |
|
933 |
/**
|
934 |
-
|
935 |
-
|
936 |
-
|
937 |
-
|
938 |
-
|
939 |
-
|
940 |
-
|
941 |
-
|
942 |
-
|
943 |
-
{
|
944 |
-
// Get options
|
945 |
-
$options = get_option('antispam_bee');
|
946 |
|
947 |
-
|
948 |
-
if ( is_array($options) ) {
|
949 |
$options = array_merge(
|
950 |
$options,
|
951 |
$data
|
952 |
);
|
953 |
-
}
|
954 |
-
else {
|
955 |
$options = $data;
|
956 |
}
|
957 |
|
958 |
-
// Update options
|
959 |
update_option(
|
960 |
'antispam_bee',
|
961 |
$options
|
962 |
);
|
963 |
|
964 |
-
// Refresh cache
|
965 |
wp_cache_set(
|
966 |
'antispam_bee',
|
967 |
$options
|
@@ -970,58 +913,47 @@ class Antispam_Bee {
|
|
970 |
|
971 |
|
972 |
|
973 |
-
/*
|
974 |
-
*
|
975 |
-
*
|
976 |
-
*
|
977 |
-
*/
|
978 |
-
|
979 |
-
/**
|
980 |
-
* Execution of the daily cronjobs
|
981 |
-
*
|
982 |
-
* @since 0.1
|
983 |
-
* @change 2.4
|
984 |
*/
|
985 |
|
986 |
-
|
987 |
-
|
988 |
-
|
989 |
-
|
|
|
|
|
|
|
|
|
990 |
return;
|
991 |
}
|
992 |
|
993 |
-
// Update timestamp
|
994 |
self::_update_option(
|
995 |
'cronjob_timestamp',
|
996 |
time()
|
997 |
);
|
998 |
|
999 |
-
// Delete spam
|
1000 |
self::_delete_old_spam();
|
1001 |
}
|
1002 |
|
1003 |
|
1004 |
/**
|
1005 |
-
|
1006 |
-
|
1007 |
-
|
1008 |
-
|
1009 |
-
|
1010 |
-
|
1011 |
-
|
1012 |
-
{
|
1013 |
-
// Number of days
|
1014 |
-
$days = (int)self::get_option('cronjob_interval');
|
1015 |
|
1016 |
-
|
1017 |
-
if ( empty($days) ) {
|
1018 |
return false;
|
1019 |
}
|
1020 |
|
1021 |
-
// Global
|
1022 |
global $wpdb;
|
1023 |
|
1024 |
-
// Delete comments
|
1025 |
$wpdb->query(
|
1026 |
$wpdb->prepare(
|
1027 |
"DELETE FROM `$wpdb->comments` WHERE `comment_approved` = 'spam' AND SUBDATE(NOW(), %d) > comment_date_gmt",
|
@@ -1029,21 +961,18 @@ class Antispam_Bee {
|
|
1029 |
)
|
1030 |
);
|
1031 |
|
1032 |
-
|
1033 |
-
$wpdb->query("OPTIMIZE TABLE `$wpdb->comments`");
|
1034 |
}
|
1035 |
|
1036 |
|
1037 |
/**
|
1038 |
-
|
1039 |
-
|
1040 |
-
|
1041 |
-
|
1042 |
-
|
1043 |
-
|
1044 |
-
|
1045 |
-
{
|
1046 |
-
if ( ! wp_next_scheduled('antispam_bee_daily_cronjob') ) {
|
1047 |
wp_schedule_event(
|
1048 |
time(),
|
1049 |
'daily',
|
@@ -1054,128 +983,101 @@ class Antispam_Bee {
|
|
1054 |
|
1055 |
|
1056 |
/**
|
1057 |
-
|
1058 |
-
|
1059 |
-
|
1060 |
-
|
1061 |
-
|
1062 |
-
|
1063 |
-
|
1064 |
-
|
1065 |
-
if ( wp_next_scheduled('antispam_bee_daily_cronjob') ) {
|
1066 |
-
wp_clear_scheduled_hook('antispam_bee_daily_cronjob');
|
1067 |
}
|
1068 |
}
|
1069 |
|
1070 |
|
1071 |
|
1072 |
-
/*
|
1073 |
-
*
|
1074 |
-
*
|
1075 |
-
*
|
1076 |
-
*/
|
1077 |
-
|
1078 |
-
/**
|
1079 |
-
* Check POST values
|
1080 |
-
*
|
1081 |
-
* @since 0.1
|
1082 |
-
* @change 2.6.3
|
1083 |
*/
|
1084 |
|
1085 |
-
|
1086 |
-
|
1087 |
-
|
1088 |
-
|
|
|
|
|
|
|
|
|
|
|
1089 |
return;
|
1090 |
}
|
1091 |
|
1092 |
-
|
1093 |
-
$
|
1094 |
-
$request_path = parse_url($request_uri, PHP_URL_PATH);
|
1095 |
|
1096 |
-
|
1097 |
-
if ( strpos($request_path, 'wp-comments-post.php') === false ) {
|
1098 |
return;
|
1099 |
}
|
1100 |
|
1101 |
-
$post_id
|
1102 |
-
// Form fields
|
1103 |
$hidden_field = self::get_key( $_POST, 'comment' );
|
1104 |
$plugin_field = self::get_key( $_POST, self::get_secret_name_for_post( $post_id ) );
|
1105 |
|
1106 |
-
|
1107 |
-
if ( empty($hidden_field) && ! empty($plugin_field) ) {
|
1108 |
$_POST['comment'] = $plugin_field;
|
1109 |
unset( $_POST[ self::get_secret_name_for_post( $post_id ) ] );
|
1110 |
} else {
|
1111 |
$_POST['ab_spam__hidden_field'] = 1;
|
1112 |
}
|
|
|
1113 |
}
|
1114 |
|
1115 |
|
1116 |
/**
|
1117 |
-
|
1118 |
-
|
1119 |
-
|
1120 |
-
|
1121 |
-
|
1122 |
-
|
1123 |
-
|
1124 |
-
|
1125 |
-
|
1126 |
-
public static function handle_incoming_request($comment)
|
1127 |
-
{
|
1128 |
-
// Add client IP
|
1129 |
$comment['comment_author_IP'] = self::get_client_ip();
|
1130 |
|
1131 |
-
|
1132 |
-
|
1133 |
-
'pre_comment_user_ip',
|
1134 |
-
array(
|
1135 |
-
__CLASS__,
|
1136 |
-
'get_client_ip'
|
1137 |
-
),
|
1138 |
-
1
|
1139 |
-
);
|
1140 |
-
|
1141 |
-
// Request params
|
1142 |
-
$request_uri = self::get_key($_SERVER, 'REQUEST_URI');
|
1143 |
-
$request_path = parse_url($request_uri, PHP_URL_PATH);
|
1144 |
|
1145 |
-
|
1146 |
-
if ( empty($request_path) ) {
|
1147 |
return self::_handle_spam_request(
|
1148 |
$comment,
|
1149 |
'empty'
|
1150 |
);
|
1151 |
}
|
1152 |
|
1153 |
-
// Defaults
|
1154 |
$ping = array(
|
1155 |
-
'types' => array('pingback', 'trackback', 'pings'),
|
1156 |
-
'allowed' => !self::get_option('ignore_pings')
|
1157 |
);
|
1158 |
|
1159 |
-
//
|
1160 |
-
|
1161 |
-
|
1162 |
-
|
|
|
1163 |
|
1164 |
-
|
1165 |
-
if ( ! empty($status['reason']) ) {
|
1166 |
return self::_handle_spam_request(
|
1167 |
$comment,
|
1168 |
$status['reason']
|
1169 |
);
|
1170 |
}
|
|
|
|
|
1171 |
|
1172 |
-
|
1173 |
-
} else if ( in_array(self::get_key($comment, 'comment_type'), $ping['types']) && $ping['allowed'] ) {
|
1174 |
-
// Verify request
|
1175 |
-
$status = self::_verify_trackback_request($comment);
|
1176 |
-
|
1177 |
-
// Treat the request as spam
|
1178 |
-
if ( ! empty($status['reason']) ) {
|
1179 |
return self::_handle_spam_request(
|
1180 |
$comment,
|
1181 |
$status['reason'],
|
@@ -1189,57 +1091,47 @@ class Antispam_Bee {
|
|
1189 |
|
1190 |
|
1191 |
/**
|
1192 |
-
|
1193 |
-
|
1194 |
-
|
1195 |
-
|
1196 |
-
|
1197 |
-
|
1198 |
-
|
1199 |
-
{
|
1200 |
-
// Frontend only
|
1201 |
-
if ( is_feed() or is_trackback() or is_robots() or self::_is_mobile() ) {
|
1202 |
return;
|
1203 |
}
|
1204 |
|
1205 |
-
|
1206 |
-
if ( !is_singular() && !self::get_option('always_allowed') ) {
|
1207 |
return;
|
1208 |
}
|
1209 |
|
1210 |
-
// Fire!
|
1211 |
ob_start(
|
1212 |
array(
|
1213 |
'Antispam_Bee',
|
1214 |
-
'replace_comment_field'
|
1215 |
)
|
1216 |
);
|
1217 |
}
|
1218 |
|
1219 |
|
1220 |
/**
|
1221 |
-
|
1222 |
-
|
1223 |
-
|
1224 |
-
|
1225 |
-
|
1226 |
-
|
1227 |
-
|
1228 |
-
|
1229 |
-
|
1230 |
-
|
1231 |
-
{
|
1232 |
-
// Empty?
|
1233 |
-
if ( empty($data) ) {
|
1234 |
return;
|
1235 |
}
|
1236 |
|
1237 |
-
|
1238 |
-
if ( ! preg_match('#<textarea.+?name=["\']comment["\']#s', $data) ) {
|
1239 |
return $data;
|
1240 |
}
|
1241 |
|
1242 |
-
/* Inject HTML */
|
1243 |
return preg_replace_callback(
|
1244 |
'/(?P<all> (?# match the whole textarea tag )
|
1245 |
<textarea (?# the opening of the textarea and some optional attributes )
|
@@ -1263,7 +1155,7 @@ class Antispam_Bee {
|
|
1263 |
)/x',
|
1264 |
array( 'Antispam_Bee', 'replace_comment_field_callback' ),
|
1265 |
$data,
|
1266 |
-
1
|
1267 |
);
|
1268 |
}
|
1269 |
|
@@ -1277,8 +1169,7 @@ class Antispam_Bee {
|
|
1277 |
* @return string The modified content string.
|
1278 |
*/
|
1279 |
public static function replace_comment_field_callback( $matches ) {
|
1280 |
-
|
1281 |
-
if ( self::get_option('time_check') ) {
|
1282 |
$init_time_field = sprintf(
|
1283 |
'<input type="hidden" name="ab_init_time" value="%d" />',
|
1284 |
time()
|
@@ -1291,7 +1182,7 @@ class Antispam_Bee {
|
|
1291 |
|
1292 |
$id_script = '';
|
1293 |
if ( ! empty( $matches['id1'] ) || ! empty( $matches['id2'] ) ) {
|
1294 |
-
$output
|
1295 |
$id_script = '<script type="text/javascript">document.getElementById("comment").setAttribute( "id", "' . esc_js( md5( time() ) ) . '" );document.getElementById("' . esc_js( self::get_secret_id_for_post( self::$_current_post_id ) ) . '").setAttribute( "id", "comment" );</script>';
|
1296 |
}
|
1297 |
|
@@ -1308,264 +1199,318 @@ class Antispam_Bee {
|
|
1308 |
|
1309 |
|
1310 |
/**
|
1311 |
-
|
1312 |
-
|
1313 |
-
|
1314 |
-
|
1315 |
-
|
1316 |
-
|
1317 |
-
|
1318 |
-
|
1319 |
-
|
1320 |
-
|
1321 |
-
|
1322 |
-
|
1323 |
-
$
|
1324 |
-
$
|
1325 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
1326 |
|
1327 |
-
|
1328 |
-
if ( empty($url) OR empty($body) ) {
|
1329 |
return array(
|
1330 |
-
'reason' => 'empty'
|
1331 |
);
|
1332 |
}
|
1333 |
|
1334 |
-
|
1335 |
-
|
|
|
|
|
|
|
1336 |
return array(
|
1337 |
-
'reason' => '
|
1338 |
);
|
1339 |
}
|
1340 |
|
1341 |
-
// Options
|
1342 |
$options = self::get_options();
|
1343 |
|
1344 |
-
|
1345 |
-
if ( $options['bbcode_check'] && self::_is_bbcode_spam($body) ) {
|
1346 |
return array(
|
1347 |
-
'reason' => 'bbcode'
|
1348 |
);
|
1349 |
}
|
1350 |
|
1351 |
-
|
1352 |
-
if ( $options['advanced_check'] && self::_is_fake_ip($ip, parse_url($url, PHP_URL_HOST)) ) {
|
1353 |
return array(
|
1354 |
-
'reason' => 'server'
|
1355 |
);
|
1356 |
}
|
1357 |
|
1358 |
-
|
1359 |
-
if ( $options['spam_ip'] && self::_is_db_spam($ip, $url) ) {
|
1360 |
return array(
|
1361 |
-
'reason' => 'localdb'
|
1362 |
);
|
1363 |
}
|
1364 |
|
1365 |
-
|
1366 |
-
if ( $options['country_code'] && self::_is_country_spam($ip) ) {
|
1367 |
return array(
|
1368 |
-
'reason' => 'country'
|
1369 |
);
|
1370 |
}
|
1371 |
|
1372 |
-
|
1373 |
-
if ( $options['translate_api'] && self::_is_lang_spam($body) ) {
|
1374 |
return array(
|
1375 |
-
'reason' => 'lang'
|
1376 |
);
|
1377 |
}
|
1378 |
-
}
|
1379 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1380 |
|
1381 |
/**
|
1382 |
-
|
1383 |
-
|
1384 |
-
|
1385 |
-
|
1386 |
-
|
1387 |
-
|
1388 |
-
|
1389 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1390 |
|
1391 |
-
|
1392 |
-
|
1393 |
-
|
1394 |
-
|
1395 |
-
|
1396 |
-
$
|
1397 |
-
|
1398 |
-
|
1399 |
-
|
1400 |
-
|
1401 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1402 |
return array(
|
1403 |
-
'reason' => 'empty'
|
1404 |
);
|
1405 |
}
|
1406 |
|
1407 |
-
|
1408 |
-
if ( empty($ip) ) {
|
1409 |
return array(
|
1410 |
-
'reason' => 'empty'
|
1411 |
);
|
1412 |
}
|
1413 |
|
1414 |
-
|
1415 |
-
if ( get_option('require_name_email') && ( empty($email) OR empty($author) ) ) {
|
1416 |
return array(
|
1417 |
-
'reason' => 'empty'
|
1418 |
);
|
1419 |
}
|
1420 |
|
1421 |
-
// Options
|
1422 |
$options = self::get_options();
|
1423 |
|
1424 |
-
|
1425 |
-
if ( $options['already_commented'] && ! empty($email) && self::_is_approved_email($email) ) {
|
1426 |
return;
|
1427 |
}
|
1428 |
|
1429 |
-
|
1430 |
-
|
1431 |
-
return;
|
1432 |
}
|
1433 |
|
1434 |
-
//
|
1435 |
-
if ( ! empty($_POST['ab_spam__hidden_field']) ) {
|
1436 |
return array(
|
1437 |
-
'reason' => 'css'
|
1438 |
);
|
1439 |
}
|
|
|
1440 |
|
1441 |
-
// Action time
|
1442 |
if ( $options['time_check'] && self::_is_shortest_time() ) {
|
1443 |
return array(
|
1444 |
-
'reason' => 'time'
|
1445 |
);
|
1446 |
}
|
1447 |
|
1448 |
-
|
1449 |
-
if ( $options['bbcode_check'] && self::_is_bbcode_spam($body) ) {
|
1450 |
return array(
|
1451 |
-
'reason' => 'bbcode'
|
1452 |
);
|
1453 |
}
|
1454 |
|
1455 |
-
|
1456 |
-
if ( $options['advanced_check'] && self::_is_fake_ip($ip) ) {
|
1457 |
return array(
|
1458 |
-
'reason' => 'server'
|
1459 |
);
|
1460 |
}
|
1461 |
|
1462 |
-
// Regex for spam
|
1463 |
if ( $options['regexp_check'] && self::_is_regexp_spam(
|
1464 |
array(
|
1465 |
-
'ip'
|
1466 |
'rawurl' => $url,
|
1467 |
-
'host'
|
1468 |
-
'body'
|
1469 |
-
'email'
|
1470 |
-
'author' => $author
|
1471 |
)
|
1472 |
) ) {
|
1473 |
return array(
|
1474 |
-
'reason' => 'regexp'
|
1475 |
);
|
1476 |
}
|
1477 |
|
1478 |
-
|
1479 |
-
if ( $options['spam_ip'] && self::_is_db_spam($ip, $url, $email) ) {
|
1480 |
return array(
|
1481 |
-
'reason' => 'localdb'
|
1482 |
);
|
1483 |
}
|
1484 |
|
1485 |
-
|
1486 |
-
if ( $options['country_code'] && self::_is_country_spam($ip) ) {
|
1487 |
return array(
|
1488 |
-
'reason' => 'country'
|
1489 |
);
|
1490 |
}
|
1491 |
|
1492 |
-
|
1493 |
-
if ( $options['translate_api'] && self::_is_lang_spam($body) ) {
|
1494 |
return array(
|
1495 |
-
'reason' => 'lang'
|
1496 |
);
|
1497 |
}
|
1498 |
}
|
1499 |
|
1500 |
|
1501 |
/**
|
1502 |
-
|
1503 |
-
|
1504 |
-
|
1505 |
-
|
1506 |
-
|
1507 |
-
|
1508 |
-
|
1509 |
-
|
1510 |
-
|
1511 |
-
|
1512 |
-
|
1513 |
-
|
1514 |
-
|
1515 |
-
|
1516 |
-
|
1517 |
-
);
|
1518 |
|
1519 |
-
|
1520 |
-
|
1521 |
-
|
1522 |
|
1523 |
-
|
1524 |
-
|
1525 |
-
|
1526 |
|
1527 |
-
|
1528 |
-
|
1529 |
|
1530 |
|
1531 |
/**
|
1532 |
-
|
1533 |
-
|
1534 |
-
|
1535 |
-
|
1536 |
-
|
1537 |
-
|
1538 |
-
|
1539 |
-
|
1540 |
-
|
1541 |
-
|
1542 |
-
|
1543 |
-
|
|
|
1544 |
return false;
|
1545 |
}
|
1546 |
|
1547 |
-
|
1548 |
-
if ( time() - $init_time < apply_filters('ab_action_time_limit', 5) ) {
|
1549 |
return true;
|
1550 |
}
|
1551 |
|
1552 |
return false;
|
1553 |
}
|
1554 |
|
1555 |
-
|
1556 |
/**
|
1557 |
-
|
1558 |
-
|
1559 |
-
|
1560 |
-
|
1561 |
-
|
1562 |
-
|
1563 |
-
|
1564 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1565 |
|
1566 |
-
|
1567 |
-
|
1568 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1569 |
$fields = array(
|
1570 |
'ip',
|
1571 |
'host',
|
@@ -1574,15 +1519,14 @@ class Antispam_Bee {
|
|
1574 |
'author',
|
1575 |
);
|
1576 |
|
1577 |
-
// Regexp
|
1578 |
$patterns = array(
|
1579 |
array(
|
1580 |
-
'host'
|
1581 |
-
'body'
|
1582 |
-
'email'
|
1583 |
),
|
1584 |
array(
|
1585 |
-
'body'
|
1586 |
),
|
1587 |
array(
|
1588 |
'author' => 'moncler|north face|vuitton|handbag|burberry|outlet|prada|cialis|viagra|maillot|oakley|ralph lauren|ray ban|iphone|プラダ',
|
@@ -1594,13 +1538,16 @@ class Antispam_Bee {
|
|
1594 |
'body' => 'target[t]?ed (visitors|traffic)|viagra|cialis',
|
1595 |
),
|
1596 |
array(
|
1597 |
-
'body'
|
1598 |
-
|
|
|
|
|
|
|
1599 |
),
|
1600 |
);
|
1601 |
|
1602 |
-
|
1603 |
-
if ( $quoted_author
|
1604 |
$patterns[] = array(
|
1605 |
'body' => sprintf(
|
1606 |
'<a.+?>%s<\/a>$',
|
@@ -1614,52 +1561,44 @@ class Antispam_Bee {
|
|
1614 |
),
|
1615 |
);
|
1616 |
$patterns[] = array(
|
1617 |
-
'email'
|
1618 |
'author' => '^[a-z0-9-\.]+\.[a-z]{2,6}$',
|
1619 |
-
'host'
|
1620 |
'^%s$',
|
1621 |
$quoted_author
|
1622 |
),
|
1623 |
);
|
1624 |
}
|
1625 |
|
1626 |
-
// Hook
|
1627 |
$patterns = apply_filters(
|
1628 |
'antispam_bee_patterns',
|
1629 |
$patterns
|
1630 |
);
|
1631 |
|
1632 |
-
// Empty?
|
1633 |
if ( ! $patterns ) {
|
1634 |
return false;
|
1635 |
}
|
1636 |
|
1637 |
-
|
1638 |
-
foreach ($patterns as $pattern) {
|
1639 |
$hits = array();
|
1640 |
|
1641 |
-
|
1642 |
-
|
1643 |
-
// Empty value?
|
1644 |
-
if ( empty($field) OR !in_array($field, $fields) OR empty($regexp) ) {
|
1645 |
continue;
|
1646 |
}
|
1647 |
|
1648 |
-
|
1649 |
-
$comment[$field] = ( function_exists('iconv') ? iconv('utf-8', 'utf-8//TRANSLIT', $comment[$field]) : $comment[$field] );
|
1650 |
|
1651 |
-
|
1652 |
-
if ( empty($comment[$field]) ) {
|
1653 |
continue;
|
1654 |
}
|
1655 |
|
1656 |
-
|
1657 |
-
|
1658 |
-
$hits[$field] = true;
|
1659 |
}
|
1660 |
}
|
1661 |
|
1662 |
-
if ( count($hits) === count($pattern) ) {
|
1663 |
return true;
|
1664 |
}
|
1665 |
}
|
@@ -1669,23 +1608,21 @@ class Antispam_Bee {
|
|
1669 |
|
1670 |
|
1671 |
/**
|
1672 |
-
|
1673 |
-
|
1674 |
-
|
1675 |
-
|
1676 |
-
|
1677 |
-
|
1678 |
-
|
1679 |
-
|
1680 |
-
|
1681 |
-
|
1682 |
-
|
1683 |
-
private static function _is_db_spam($ip, $url = '', $email = '')
|
1684 |
-
{
|
1685 |
-
// Global
|
1686 |
global $wpdb;
|
1687 |
|
1688 |
-
|
|
|
1689 |
select
|
1690 |
meta_value as ip
|
1691 |
from
|
@@ -1696,9 +1633,9 @@ class Antispam_Bee {
|
|
1696 |
AND meta.meta_key = "antispam_bee_iphash"
|
1697 |
AND comments.comment_approved="spam"';
|
1698 |
$hashed_ips = $wpdb->get_col( $sql );
|
1699 |
-
if( ! empty( $hashed_ips) ) {
|
1700 |
foreach ( $hashed_ips as $hash ) {
|
1701 |
-
if( wp_check_password($ip, $hash) ) {
|
1702 |
return true;
|
1703 |
}
|
1704 |
}
|
@@ -1706,53 +1643,51 @@ class Antispam_Bee {
|
|
1706 |
|
1707 |
$params = array();
|
1708 |
$filter = array();
|
1709 |
-
|
1710 |
-
if ( ! empty($url) ) {
|
1711 |
$filter[] = '`comment_author_url` = %s';
|
1712 |
-
$params[] = wp_unslash($url);
|
1713 |
}
|
1714 |
|
1715 |
-
|
1716 |
-
if ( ! empty($email) ) {
|
1717 |
$filter[] = '`comment_author_email` = %s';
|
1718 |
-
$params[] = wp_unslash($email);
|
1719 |
}
|
1720 |
-
|
1721 |
-
if( empty( $params ) ) {
|
1722 |
return false;
|
1723 |
}
|
1724 |
|
1725 |
-
//
|
|
|
|
|
|
|
1726 |
$result = $wpdb->get_var(
|
1727 |
$wpdb->prepare(
|
1728 |
sprintf(
|
1729 |
"SELECT `comment_ID` FROM `$wpdb->comments` WHERE `comment_approved` = 'spam' AND (%s) LIMIT 1",
|
1730 |
-
|
1731 |
),
|
1732 |
$params
|
1733 |
)
|
1734 |
);
|
|
|
|
|
1735 |
|
1736 |
-
return !empty($result);
|
1737 |
}
|
1738 |
|
1739 |
|
1740 |
/**
|
1741 |
-
|
1742 |
-
|
1743 |
-
|
1744 |
-
|
1745 |
-
|
1746 |
-
|
1747 |
-
|
1748 |
-
|
1749 |
-
|
1750 |
-
private static function _is_country_spam($ip)
|
1751 |
-
{
|
1752 |
-
// Get options
|
1753 |
$options = self::get_options();
|
1754 |
|
1755 |
-
// White & Black
|
1756 |
$white = preg_split(
|
1757 |
'/[\s,;]+/',
|
1758 |
$options['country_white'],
|
@@ -1766,90 +1701,75 @@ class Antispam_Bee {
|
|
1766 |
PREG_SPLIT_NO_EMPTY
|
1767 |
);
|
1768 |
|
1769 |
-
|
1770 |
-
if ( empty($white) && empty($black) ) {
|
1771 |
return false;
|
1772 |
}
|
1773 |
|
1774 |
-
// IP 2 Country API
|
1775 |
$response = wp_safe_remote_head(
|
1776 |
esc_url_raw(
|
1777 |
sprintf(
|
1778 |
'https://api.ip2country.info/ip?%s',
|
1779 |
-
self::_anonymize_ip($ip)
|
1780 |
),
|
1781 |
'https'
|
1782 |
)
|
1783 |
);
|
1784 |
|
1785 |
-
|
1786 |
-
if ( is_wp_error($response) ) {
|
1787 |
return false;
|
1788 |
}
|
1789 |
|
1790 |
-
|
1791 |
-
if ( wp_remote_retrieve_response_code($response) !== 200 ) {
|
1792 |
return false;
|
1793 |
}
|
1794 |
|
1795 |
-
|
1796 |
-
$country = (string)wp_remote_retrieve_header($response, 'x-country-code');
|
1797 |
|
1798 |
-
|
1799 |
-
if ( empty($country) OR strlen($country) !== 2 ) {
|
1800 |
return false;
|
1801 |
}
|
1802 |
|
1803 |
-
|
1804 |
-
|
1805 |
-
return ( in_array($country, $black) );
|
1806 |
}
|
1807 |
|
1808 |
-
|
1809 |
-
return ( ! in_array($country, $white) );
|
1810 |
}
|
1811 |
|
1812 |
|
1813 |
/**
|
1814 |
-
|
1815 |
-
|
1816 |
-
|
1817 |
-
|
1818 |
-
|
1819 |
-
|
1820 |
-
|
1821 |
-
|
1822 |
-
|
1823 |
-
|
1824 |
-
{
|
1825 |
-
return (bool) preg_match('/\[url[=\]].*\[\/url\]/is', $body);
|
1826 |
}
|
1827 |
|
1828 |
|
1829 |
/**
|
1830 |
-
|
1831 |
-
|
1832 |
-
|
1833 |
-
|
1834 |
-
|
1835 |
-
|
1836 |
-
|
1837 |
-
|
1838 |
-
|
1839 |
-
private static function _is_approved_email($email)
|
1840 |
-
{
|
1841 |
-
// Global
|
1842 |
global $wpdb;
|
1843 |
|
1844 |
-
// Search
|
1845 |
$result = $wpdb->get_var(
|
1846 |
$wpdb->prepare(
|
1847 |
"SELECT `comment_ID` FROM `$wpdb->comments` WHERE `comment_approved` = '1' AND `comment_author_email` = %s LIMIT 1",
|
1848 |
-
wp_unslash($email)
|
1849 |
)
|
1850 |
);
|
1851 |
|
1852 |
-
// Found?
|
1853 |
if ( $result ) {
|
1854 |
return true;
|
1855 |
}
|
@@ -1859,44 +1779,37 @@ class Antispam_Bee {
|
|
1859 |
|
1860 |
|
1861 |
/**
|
1862 |
-
|
1863 |
-
|
1864 |
-
|
1865 |
-
|
1866 |
-
|
1867 |
-
|
1868 |
-
|
1869 |
-
|
1870 |
-
|
1871 |
-
|
1872 |
-
|
1873 |
-
{
|
1874 |
-
// Remote Host
|
1875 |
-
$host_by_ip = gethostbyaddr($client_ip);
|
1876 |
|
1877 |
-
|
1878 |
-
|
1879 |
-
return $client_ip != $host_by_ip;
|
1880 |
}
|
1881 |
|
1882 |
-
|
1883 |
-
|
1884 |
-
$ip_by_host = gethostbyname($host_by_ip);
|
1885 |
|
1886 |
if ( $ip_by_host === $host_by_ip ) {
|
1887 |
return false;
|
1888 |
}
|
1889 |
-
|
1890 |
-
// IPv4 and Trackback
|
1891 |
} else {
|
1892 |
if ( $host_by_ip === $client_ip ) {
|
1893 |
return true;
|
1894 |
}
|
1895 |
|
1896 |
-
$ip_by_host = gethostbyname($client_host);
|
1897 |
}
|
1898 |
|
1899 |
-
if ( strpos( $client_ip, self::_cut_ip($ip_by_host) ) === false ) {
|
1900 |
return true;
|
1901 |
}
|
1902 |
|
@@ -1908,103 +1821,282 @@ class Antispam_Bee {
|
|
1908 |
*
|
1909 |
* @since 2.0
|
1910 |
* @change 2.6.6
|
1911 |
-
* @change 2.
|
1912 |
*
|
1913 |
* @param string $comment_content Content of the comment.
|
1914 |
*
|
1915 |
-
* @return boolean TRUE if it is spam
|
1916 |
*/
|
1917 |
-
|
1918 |
private static function _is_lang_spam( $comment_content ) {
|
1919 |
-
// User defined language
|
1920 |
$allowed_lang = (array) self::get_option( 'translate_lang' );
|
1921 |
|
1922 |
-
// Make comment text plain
|
1923 |
$comment_text = wp_strip_all_tags( $comment_content );
|
1924 |
|
1925 |
-
|
1926 |
-
if ( empty( $allowed_lang )
|
1927 |
-
|| empty( $comment_text )
|
1928 |
-
) {
|
1929 |
-
return false;
|
1930 |
-
}
|
1931 |
-
|
1932 |
-
// Trim comment text
|
1933 |
-
if ( ! $query_text = wp_trim_words( $comment_text, 10, '' ) ) {
|
1934 |
return false;
|
1935 |
}
|
1936 |
|
1937 |
/**
|
1938 |
-
*
|
1939 |
*
|
1940 |
-
* @since 2.
|
1941 |
*
|
1942 |
-
* @param
|
|
|
1943 |
*
|
1944 |
-
* @return string
|
1945 |
*/
|
1946 |
-
$
|
1947 |
-
|
1948 |
-
|
1949 |
-
|
1950 |
-
)
|
1951 |
-
);
|
1952 |
|
1953 |
-
|
1954 |
-
|
1955 |
-
|
1956 |
-
|
1957 |
-
|
1958 |
-
|
1959 |
-
|
1960 |
-
'https://www.googleapis.com/language/translate/v2/detect'
|
1961 |
-
)
|
1962 |
);
|
1963 |
|
1964 |
-
// Skip on error
|
1965 |
if ( is_wp_error( $response )
|
1966 |
-
|
1967 |
return false;
|
1968 |
}
|
1969 |
|
1970 |
-
|
1971 |
-
if ( ! $
|
1972 |
return false;
|
1973 |
}
|
1974 |
|
1975 |
-
|
1976 |
-
if ( ! $
|
1977 |
return false;
|
1978 |
}
|
1979 |
|
1980 |
-
|
1981 |
-
|
1982 |
-
|
1983 |
-
|
1984 |
-
|
1985 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1986 |
}
|
1987 |
|
1988 |
-
return
|
1989 |
}
|
1990 |
|
1991 |
/**
|
1992 |
-
|
1993 |
-
|
1994 |
-
|
1995 |
-
|
1996 |
-
|
1997 |
-
|
1998 |
-
|
1999 |
-
|
2000 |
-
|
2001 |
-
|
2002 |
-
|
2003 |
-
{
|
2004 |
-
$separator = ( self::_is_ipv4($ip) ? '.' : ':' );
|
2005 |
|
2006 |
return str_replace(
|
2007 |
-
( $cut_end ? strrchr( $ip, $separator) : strstr( $ip, $separator) ),
|
2008 |
'',
|
2009 |
$ip
|
2010 |
);
|
@@ -2012,37 +2104,33 @@ class Antispam_Bee {
|
|
2012 |
|
2013 |
|
2014 |
/**
|
2015 |
-
|
2016 |
-
|
2017 |
-
|
2018 |
-
|
2019 |
-
|
2020 |
-
|
2021 |
-
|
2022 |
-
|
2023 |
-
|
2024 |
-
|
2025 |
-
|
2026 |
-
if ( self::_is_ipv4($ip) ) {
|
2027 |
-
return self::_cut_ip($ip). '.0';
|
2028 |
}
|
2029 |
|
2030 |
-
return self::_cut_ip($ip, false). ':0:0:0:0:0:0:0';
|
2031 |
}
|
2032 |
|
2033 |
|
2034 |
/**
|
2035 |
-
|
2036 |
-
|
2037 |
-
|
2038 |
-
|
2039 |
-
|
2040 |
-
|
2041 |
-
|
2042 |
-
|
2043 |
-
|
2044 |
-
private static function _reverse_ip($ip)
|
2045 |
-
{
|
2046 |
return implode(
|
2047 |
'.',
|
2048 |
array_reverse(
|
@@ -2056,150 +2144,129 @@ class Antispam_Bee {
|
|
2056 |
|
2057 |
|
2058 |
/**
|
2059 |
-
|
2060 |
-
|
2061 |
-
|
2062 |
-
|
2063 |
-
|
2064 |
-
|
2065 |
-
|
2066 |
-
|
2067 |
-
|
2068 |
-
|
2069 |
-
{
|
2070 |
-
if ( function_exists('filter_var') ) {
|
2071 |
return filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) !== false;
|
2072 |
} else {
|
2073 |
-
return preg_match('/^\d{1,3}(\.\d{1,3}){3,3}$/', $ip);
|
2074 |
}
|
2075 |
}
|
2076 |
|
2077 |
|
2078 |
/**
|
2079 |
-
|
2080 |
-
|
2081 |
-
|
2082 |
-
|
2083 |
-
|
2084 |
-
|
2085 |
-
|
2086 |
-
|
2087 |
-
|
2088 |
-
|
2089 |
-
{
|
2090 |
-
if ( function_exists('filter_var') ) {
|
2091 |
return filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) !== false;
|
2092 |
} else {
|
2093 |
-
return ! self::_is_ipv4($ip);
|
2094 |
}
|
2095 |
}
|
2096 |
|
2097 |
|
2098 |
/**
|
2099 |
-
|
2100 |
-
|
2101 |
-
|
2102 |
-
|
2103 |
-
|
2104 |
-
|
2105 |
-
|
2106 |
-
|
2107 |
-
|
2108 |
-
{
|
2109 |
-
return strpos(TEMPLATEPATH, 'wptouch');
|
2110 |
}
|
2111 |
|
2112 |
|
2113 |
|
2114 |
-
/*
|
2115 |
-
*
|
2116 |
-
*
|
2117 |
-
*
|
2118 |
-
*/
|
2119 |
|
2120 |
/**
|
2121 |
-
|
2122 |
-
|
2123 |
-
|
2124 |
-
|
2125 |
-
|
2126 |
-
|
2127 |
-
|
2128 |
-
|
2129 |
-
|
2130 |
-
|
|
|
2131 |
|
2132 |
-
private static function _handle_spam_request($comment, $reason, $is_ping = false)
|
2133 |
-
{
|
2134 |
-
// Options
|
2135 |
$options = self::get_options();
|
2136 |
|
2137 |
-
|
2138 |
-
$
|
2139 |
-
$spam_notice = !$options['no_notice'];
|
2140 |
|
2141 |
-
// Filter settings
|
2142 |
$ignore_filter = $options['ignore_filter'];
|
2143 |
-
$ignore_type
|
2144 |
-
$ignore_reason = in_array($reason, (array)$options['ignore_reasons']);
|
2145 |
|
2146 |
-
// Remember spam
|
2147 |
-
self::_update_spam_log($comment);
|
2148 |
self::_update_spam_count();
|
2149 |
self::_update_daily_stats();
|
2150 |
|
2151 |
-
// Delete spam
|
2152 |
if ( $spam_remove ) {
|
2153 |
self::_go_in_peace();
|
2154 |
}
|
2155 |
|
2156 |
-
|
2157 |
-
add_action(
|
2158 |
-
'comment_post',
|
2159 |
-
array(
|
2160 |
-
__CLASS__,
|
2161 |
-
'save_ip_hash',
|
2162 |
-
),
|
2163 |
-
10,
|
2164 |
-
3
|
2165 |
-
);
|
2166 |
-
|
2167 |
-
// Handle types
|
2168 |
-
if ( $ignore_filter && (( $ignore_type == 1 && $is_ping ) or ( $ignore_type == 2 && !$is_ping )) ) {
|
2169 |
self::_go_in_peace();
|
2170 |
}
|
2171 |
|
2172 |
-
// Spam reason
|
2173 |
if ( $ignore_reason ) {
|
2174 |
self::_go_in_peace();
|
2175 |
}
|
2176 |
self::$_reason = $reason;
|
2177 |
|
2178 |
-
// Mark spam
|
2179 |
add_filter(
|
2180 |
'pre_comment_approved',
|
2181 |
array(
|
2182 |
__CLASS__,
|
2183 |
-
'return_spam'
|
2184 |
)
|
2185 |
);
|
2186 |
|
2187 |
-
// Send e-mail
|
2188 |
add_action(
|
2189 |
'comment_post',
|
2190 |
array(
|
2191 |
__CLASS__,
|
2192 |
-
'send_mail_notification'
|
2193 |
)
|
2194 |
);
|
2195 |
|
2196 |
-
// Spam reason as comment meta
|
2197 |
if ( $spam_notice ) {
|
2198 |
add_action(
|
2199 |
'comment_post',
|
2200 |
array(
|
2201 |
__CLASS__,
|
2202 |
-
'add_spam_reason_to_comment'
|
2203 |
)
|
2204 |
);
|
2205 |
}
|
@@ -2209,32 +2276,27 @@ class Antispam_Bee {
|
|
2209 |
|
2210 |
|
2211 |
/**
|
2212 |
-
|
2213 |
-
|
2214 |
-
|
2215 |
-
|
2216 |
-
|
2217 |
-
|
2218 |
-
|
2219 |
-
|
2220 |
-
|
2221 |
-
|
2222 |
-
{
|
2223 |
-
// Skip logfile?
|
2224 |
-
if ( ! defined('ANTISPAM_BEE_LOG_FILE') OR ! ANTISPAM_BEE_LOG_FILE OR ! is_writable(ANTISPAM_BEE_LOG_FILE) OR validate_file(ANTISPAM_BEE_LOG_FILE) === 1 ) {
|
2225 |
return false;
|
2226 |
}
|
2227 |
|
2228 |
-
// Compose entry
|
2229 |
$entry = sprintf(
|
2230 |
'%s comment for post=%d from host=%s marked as spam%s',
|
2231 |
-
current_time('mysql'),
|
2232 |
$comment['comment_post_ID'],
|
2233 |
$comment['comment_author_IP'],
|
2234 |
PHP_EOL
|
2235 |
);
|
2236 |
|
2237 |
-
// Write
|
2238 |
file_put_contents(
|
2239 |
ANTISPAM_BEE_LOG_FILE,
|
2240 |
$entry,
|
@@ -2244,52 +2306,51 @@ class Antispam_Bee {
|
|
2244 |
|
2245 |
|
2246 |
/**
|
2247 |
-
|
2248 |
-
|
2249 |
-
|
2250 |
-
|
2251 |
-
|
2252 |
-
|
2253 |
-
|
2254 |
-
|
2255 |
-
status_header(403);
|
2256 |
-
die('Spam deleted.');
|
2257 |
}
|
2258 |
|
2259 |
|
2260 |
/**
|
2261 |
-
|
2262 |
-
|
2263 |
-
|
2264 |
-
|
2265 |
-
|
2266 |
-
|
2267 |
-
|
2268 |
-
|
2269 |
-
|
2270 |
-
|
2271 |
-
if ( isset($_SERVER['HTTP_CLIENT_IP']) ) {
|
2272 |
-
$ip = $_SERVER['HTTP_CLIENT_IP'];
|
2273 |
-
}
|
2274 |
-
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
|
2275 |
-
}
|
2276 |
-
$ip = $_SERVER['HTTP_X_FORWARDED'];
|
2277 |
-
}
|
2278 |
-
$ip = $_SERVER['HTTP_FORWARDED_FOR'];
|
2279 |
-
}
|
2280 |
-
$ip = $_SERVER['HTTP_FORWARDED'];
|
2281 |
-
}
|
2282 |
-
$ip = $_SERVER['REMOTE_ADDR'];
|
2283 |
} else {
|
2284 |
return '';
|
2285 |
}
|
|
|
2286 |
|
2287 |
-
if ( strpos($ip, ',') !== false ) {
|
2288 |
-
$ips = explode(',', $ip);
|
2289 |
-
$ip
|
2290 |
}
|
2291 |
|
2292 |
-
if ( function_exists('filter_var') ) {
|
2293 |
return filter_var(
|
2294 |
$ip,
|
2295 |
FILTER_VALIDATE_IP
|
@@ -2303,18 +2364,15 @@ class Antispam_Bee {
|
|
2303 |
);
|
2304 |
}
|
2305 |
|
2306 |
-
|
2307 |
/**
|
2308 |
-
|
2309 |
-
|
2310 |
-
|
2311 |
-
|
2312 |
-
|
2313 |
-
|
2314 |
-
|
2315 |
-
|
2316 |
-
public static function add_spam_reason_to_comment( $comment_id )
|
2317 |
-
{
|
2318 |
add_comment_meta(
|
2319 |
$comment_id,
|
2320 |
'antispam_bee_reason',
|
@@ -2322,9 +2380,13 @@ class Antispam_Bee {
|
|
2322 |
);
|
2323 |
}
|
2324 |
|
2325 |
-
|
2326 |
-
|
2327 |
-
|
|
|
|
|
|
|
|
|
2328 |
add_comment_meta(
|
2329 |
$comment_id,
|
2330 |
'antispam_bee_iphash',
|
@@ -2332,23 +2394,27 @@ class Antispam_Bee {
|
|
2332 |
);
|
2333 |
}
|
2334 |
|
2335 |
-
|
2336 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
2337 |
return wp_hash_password( $ip );
|
2338 |
}
|
2339 |
|
2340 |
|
2341 |
/**
|
2342 |
-
|
2343 |
-
|
2344 |
-
|
2345 |
-
|
2346 |
-
|
2347 |
-
|
2348 |
-
|
2349 |
-
|
2350 |
-
public static function delete_spam_reason_by_comment( $comment_id )
|
2351 |
-
{
|
2352 |
delete_comment_meta(
|
2353 |
$comment_id,
|
2354 |
'antispam_bee_reason'
|
@@ -2359,8 +2425,6 @@ class Antispam_Bee {
|
|
2359 |
* Get the current post ID.
|
2360 |
*
|
2361 |
* @since 2.7.1
|
2362 |
-
*
|
2363 |
-
* @param integer $comment_id Comment ID
|
2364 |
*/
|
2365 |
public static function populate_post_id() {
|
2366 |
|
@@ -2371,132 +2435,126 @@ class Antispam_Bee {
|
|
2371 |
|
2372 |
|
2373 |
/**
|
2374 |
-
|
2375 |
-
|
2376 |
-
|
2377 |
-
|
2378 |
-
|
2379 |
-
|
2380 |
-
|
2381 |
-
|
2382 |
-
|
2383 |
-
|
2384 |
-
|
2385 |
-
public static function send_mail_notification($id)
|
2386 |
-
{
|
2387 |
-
// Options
|
2388 |
$options = self::get_options();
|
2389 |
|
2390 |
-
|
2391 |
-
if ( !$options['email_notify'] ) {
|
2392 |
return $id;
|
2393 |
}
|
2394 |
|
2395 |
-
|
2396 |
-
$comment = get_comment($id, ARRAY_A);
|
2397 |
|
2398 |
-
|
2399 |
-
if ( empty($comment) ) {
|
2400 |
return $id;
|
2401 |
}
|
2402 |
|
2403 |
-
|
2404 |
-
if ( ! $post
|
2405 |
return $id;
|
2406 |
}
|
2407 |
|
2408 |
-
// Load the language
|
2409 |
self::load_plugin_lang();
|
2410 |
|
2411 |
-
// Subject
|
2412 |
$subject = sprintf(
|
2413 |
'[%s] %s',
|
2414 |
stripslashes_deep(
|
2415 |
html_entity_decode(
|
2416 |
-
get_bloginfo('name'),
|
2417 |
ENT_QUOTES
|
2418 |
)
|
2419 |
),
|
2420 |
-
esc_html__('Comment marked as spam', 'antispam-bee')
|
2421 |
);
|
2422 |
|
2423 |
-
// Content
|
2424 |
-
|
|
|
2425 |
$content = sprintf(
|
2426 |
'-- %s --',
|
2427 |
-
esc_html__('Content removed by Antispam Bee', 'antispam-bee')
|
2428 |
);
|
2429 |
}
|
2430 |
|
2431 |
-
// Body
|
2432 |
$body = sprintf(
|
2433 |
"%s \"%s\"\r\n\r\n",
|
2434 |
-
esc_html__('New spam comment on your post', 'antispam-bee'),
|
2435 |
-
strip_tags($post->post_title)
|
2436 |
-
).sprintf(
|
2437 |
"%s: %s\r\n",
|
2438 |
-
esc_html__('Author', 'antispam-bee'),
|
2439 |
-
( empty($comment['comment_author']) ? '' : strip_tags($comment['comment_author']) )
|
2440 |
-
).sprintf(
|
2441 |
"URL: %s\r\n",
|
2442 |
-
// empty check exists
|
2443 |
-
esc_url($comment['comment_author_url'])
|
2444 |
-
).sprintf(
|
2445 |
"%s: %s\r\n",
|
2446 |
-
esc_html__('Type', 'antispam-bee'),
|
2447 |
-
|
2448 |
-
).sprintf(
|
2449 |
"Whois: http://whois.arin.net/rest/ip/%s\r\n",
|
2450 |
$comment['comment_author_IP']
|
2451 |
-
).sprintf(
|
2452 |
"%s: %s\r\n\r\n",
|
2453 |
-
esc_html__('Spam Reason', 'antispam-bee'),
|
2454 |
-
|
2455 |
-
).sprintf(
|
2456 |
"%s\r\n\r\n\r\n",
|
2457 |
$content
|
2458 |
-
).(
|
2459 |
EMPTY_TRASH_DAYS ? (
|
2460 |
sprintf(
|
2461 |
"%s: %s\r\n",
|
2462 |
-
esc_html__('Trash it', 'antispam-bee'),
|
2463 |
-
admin_url('comment.php?action=trash&c='
|
2464 |
)
|
2465 |
) : (
|
2466 |
sprintf(
|
2467 |
"%s: %s\r\n",
|
2468 |
-
esc_html__('Delete it', 'antispam-bee'),
|
2469 |
-
admin_url('comment.php?action=delete&c='
|
2470 |
)
|
2471 |
)
|
2472 |
-
).sprintf(
|
2473 |
-
|
2474 |
-
esc_html__('Approve it', 'antispam-bee'),
|
2475 |
-
admin_url('comment.php?action=approve&c='
|
2476 |
-
).sprintf(
|
2477 |
"%s: %s\r\n\r\n",
|
2478 |
-
esc_html__('Spam list', 'antispam-bee'),
|
2479 |
-
admin_url('edit-comments.php?comment_status=spam')
|
2480 |
-
).sprintf(
|
2481 |
"%s\r\n%s\r\n",
|
2482 |
-
esc_html__('Notify message by Antispam Bee', 'antispam-bee'),
|
2483 |
-
esc_html__('http://antispambee.com', 'antispam-bee')
|
2484 |
);
|
2485 |
|
2486 |
-
// Send
|
2487 |
wp_mail(
|
2488 |
/**
|
2489 |
-
* Filters the recipients of the spam notification
|
|
|
2490 |
* @param array The recipients array.
|
2491 |
-
|
2492 |
apply_filters(
|
2493 |
'antispam_bee_notification_recipients',
|
2494 |
-
array( get_bloginfo('admin_email') )
|
2495 |
),
|
2496 |
/**
|
2497 |
-
* Filters the subject of the spam notification
|
|
|
2498 |
* @param string $subject subject line.
|
2499 |
-
|
2500 |
apply_filters(
|
2501 |
'antispam_bee_notification_subject',
|
2502 |
$subject
|
@@ -2509,121 +2567,116 @@ class Antispam_Bee {
|
|
2509 |
|
2510 |
|
2511 |
|
2512 |
-
/*
|
2513 |
-
*
|
2514 |
-
*
|
2515 |
-
*
|
2516 |
-
*/
|
2517 |
-
|
2518 |
-
/**
|
2519 |
-
* Return the number of spam comments
|
2520 |
-
*
|
2521 |
-
* @since 0.1
|
2522 |
-
* @change 2.4
|
2523 |
-
*
|
2524 |
-
* @param intval $count Number of spam comments
|
2525 |
*/
|
2526 |
|
2527 |
-
|
2528 |
-
|
2529 |
-
|
2530 |
-
|
|
|
|
|
|
|
|
|
|
|
2531 |
|
2532 |
-
// Fire
|
2533 |
-
return ( get_locale()
|
2534 |
}
|
2535 |
|
2536 |
|
2537 |
/**
|
2538 |
-
|
2539 |
-
|
2540 |
-
|
2541 |
-
|
2542 |
-
|
2543 |
-
|
2544 |
-
public static function the_spam_count()
|
2545 |
-
{
|
2546 |
echo esc_html( self::_get_spam_count() );
|
2547 |
}
|
2548 |
|
2549 |
|
2550 |
/**
|
2551 |
-
|
2552 |
-
|
2553 |
-
|
2554 |
-
|
2555 |
-
|
2556 |
-
|
2557 |
-
|
2558 |
-
|
2559 |
-
// Skip if not enabled
|
2560 |
-
if ( ! self::get_option('dashboard_count') ) {
|
2561 |
return;
|
2562 |
}
|
2563 |
|
2564 |
self::_update_option(
|
2565 |
'spam_count',
|
2566 |
-
intval( self::get_option('spam_count') + 1 )
|
2567 |
);
|
2568 |
}
|
2569 |
|
2570 |
-
|
2571 |
/**
|
2572 |
-
|
2573 |
-
|
2574 |
-
|
2575 |
-
|
2576 |
-
|
2577 |
-
|
2578 |
-
|
2579 |
-
|
2580 |
-
// Skip if not enabled
|
2581 |
-
if ( ! self::get_option('dashboard_chart') ) {
|
2582 |
return;
|
2583 |
}
|
2584 |
|
2585 |
-
// Init
|
2586 |
-
$stats = (array)self::get_option('daily_stats');
|
2587 |
-
$today = (int)strtotime('today');
|
2588 |
|
2589 |
-
// Count up
|
2590 |
-
if ( array_key_exists($today, $stats) ) {
|
2591 |
-
$stats[$today] ++;
|
2592 |
} else {
|
2593 |
-
$stats[$today] = 1;
|
2594 |
}
|
2595 |
|
2596 |
-
// Sort
|
2597 |
-
krsort($stats, SORT_NUMERIC);
|
2598 |
|
2599 |
-
// Save
|
2600 |
self::_update_option(
|
2601 |
'daily_stats',
|
2602 |
-
array_slice($stats, 0, 31, true)
|
2603 |
);
|
2604 |
}
|
2605 |
|
2606 |
/**
|
2607 |
* Returns the secret of a post used in the textarea name attribute.
|
2608 |
*
|
2609 |
-
* @param int $post_id
|
2610 |
*
|
2611 |
* @return string
|
2612 |
*/
|
2613 |
public static function get_secret_name_for_post( $post_id ) {
|
2614 |
|
2615 |
-
|
|
|
|
|
|
|
|
|
2616 |
|
2617 |
/**
|
2618 |
* Filters the secret for a post, which is used in the textarea name attribute.
|
2619 |
*
|
2620 |
* @param string $secret The secret.
|
2621 |
* @param int $post_id The post ID.
|
|
|
2622 |
*/
|
2623 |
return apply_filters(
|
2624 |
'ab_get_secret_name_for_post',
|
2625 |
$secret,
|
2626 |
-
(int) $post_id
|
|
|
2627 |
);
|
2628 |
|
2629 |
}
|
@@ -2631,24 +2684,30 @@ class Antispam_Bee {
|
|
2631 |
/**
|
2632 |
* Returns the secret of a post used in the textarea id attribute.
|
2633 |
*
|
2634 |
-
* @param int $post_id
|
2635 |
*
|
2636 |
* @return string
|
2637 |
*/
|
2638 |
public static function get_secret_id_for_post( $post_id ) {
|
2639 |
|
2640 |
-
|
|
|
|
|
|
|
|
|
2641 |
|
2642 |
/**
|
2643 |
* Filters the secret for a post, which is used in the textarea id attribute.
|
2644 |
*
|
2645 |
* @param string $secret The secret.
|
2646 |
* @param int $post_id The post ID.
|
|
|
2647 |
*/
|
2648 |
return apply_filters(
|
2649 |
'ab_get_secret_id_for_post',
|
2650 |
$secret,
|
2651 |
-
(int) $post_id
|
|
|
2652 |
);
|
2653 |
}
|
2654 |
|
@@ -2663,41 +2722,57 @@ class Antispam_Bee {
|
|
2663 |
|
2664 |
return 'spam';
|
2665 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2666 |
}
|
2667 |
|
2668 |
|
2669 |
-
// Fire
|
2670 |
add_action(
|
2671 |
'plugins_loaded',
|
2672 |
array(
|
2673 |
'Antispam_Bee',
|
2674 |
-
'init'
|
2675 |
)
|
2676 |
);
|
2677 |
|
2678 |
-
// Activation
|
2679 |
register_activation_hook(
|
2680 |
__FILE__,
|
2681 |
array(
|
2682 |
'Antispam_Bee',
|
2683 |
-
'activate'
|
2684 |
)
|
2685 |
);
|
2686 |
|
2687 |
-
// Deactivation
|
2688 |
register_deactivation_hook(
|
2689 |
__FILE__,
|
2690 |
array(
|
2691 |
'Antispam_Bee',
|
2692 |
-
'deactivate'
|
2693 |
)
|
2694 |
);
|
2695 |
|
2696 |
-
// Uninstall
|
2697 |
register_uninstall_hook(
|
2698 |
__FILE__,
|
2699 |
array(
|
2700 |
'Antispam_Bee',
|
2701 |
-
'uninstall'
|
2702 |
)
|
2703 |
);
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* Plugin Name: Antispam Bee
|
4 |
+
* Description: Antispam plugin with a sophisticated toolset for effective day to day comment and trackback spam-fighting. Built with data protection and privacy in mind.
|
5 |
+
* Author: pluginkollektiv
|
6 |
+
* Author URI: https://pluginkollektiv.org
|
7 |
+
* Plugin URI: https://wordpress.org/plugins/antispam-bee/
|
8 |
+
* Text Domain: antispam-bee
|
9 |
+
* Domain Path: /lang
|
10 |
+
* License: GPLv2 or later
|
11 |
+
* License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
12 |
+
* Version: 2.9.0
|
13 |
+
*
|
14 |
+
* @package Antispam Bee
|
15 |
+
**/
|
16 |
|
17 |
/*
|
18 |
* Copyright (C) 2009-2015 Sergej Müller
|
36 |
// Make sure this file is only run from within the WordPress context.
|
37 |
defined( 'ABSPATH' ) || exit;
|
38 |
|
|
|
39 |
/**
|
40 |
+
* Antispam_Bee
|
41 |
+
*
|
42 |
+
* @since 0.1
|
43 |
+
* @change 2.4
|
44 |
+
*/
|
|
|
45 |
class Antispam_Bee {
|
46 |
|
47 |
+
/**
|
48 |
+
* The option defaults.
|
49 |
+
*
|
50 |
+
* @var array
|
51 |
+
*/
|
52 |
public static $defaults;
|
53 |
+
|
54 |
+
/**
|
55 |
+
* The base.
|
56 |
+
*
|
57 |
+
* @var string
|
58 |
+
*/
|
59 |
private static $_base;
|
60 |
+
|
61 |
+
/**
|
62 |
+
* The salt.
|
63 |
+
*
|
64 |
+
* @var string
|
65 |
+
*/
|
66 |
private static $_salt;
|
67 |
+
|
68 |
+
|
69 |
+
/**
|
70 |
+
* The spam reason.
|
71 |
+
*
|
72 |
+
* @var string
|
73 |
+
*/
|
74 |
private static $_reason;
|
|
|
75 |
|
76 |
+
/**
|
77 |
+
* The current Post ID.
|
78 |
+
*
|
79 |
+
* @var int
|
80 |
+
*/
|
81 |
+
private static $_current_post_id;
|
82 |
|
83 |
/**
|
84 |
+
* "Constructor" of the class
|
85 |
+
*
|
86 |
+
* @since 0.1
|
87 |
+
* @change 2.6.4
|
88 |
+
*/
|
89 |
+
public static function init() {
|
90 |
+
add_action(
|
91 |
+
'unspam_comment',
|
92 |
+
array(
|
93 |
+
__CLASS__,
|
94 |
+
'delete_spam_reason_by_comment',
|
95 |
+
)
|
96 |
+
);
|
97 |
|
98 |
+
if ( ( defined( 'DOING_AJAX' ) && DOING_AJAX ) || ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
99 |
return;
|
100 |
}
|
101 |
|
|
|
102 |
self::_init_internal_vars();
|
103 |
|
104 |
+
if ( defined( 'DOING_CRON' ) ) {
|
|
|
105 |
add_action(
|
106 |
'antispam_bee_daily_cronjob',
|
107 |
array(
|
108 |
__CLASS__,
|
109 |
+
'start_daily_cronjob',
|
110 |
)
|
111 |
);
|
112 |
|
|
|
113 |
} elseif ( is_admin() ) {
|
|
|
114 |
add_action(
|
115 |
'admin_menu',
|
116 |
array(
|
117 |
__CLASS__,
|
118 |
+
'add_sidebar_menu',
|
119 |
)
|
120 |
);
|
121 |
|
122 |
+
if ( self::_current_page( 'dashboard' ) ) {
|
|
|
123 |
add_action(
|
124 |
'init',
|
125 |
array(
|
126 |
__CLASS__,
|
127 |
+
'load_plugin_lang',
|
128 |
)
|
129 |
);
|
130 |
add_filter(
|
131 |
'dashboard_glance_items',
|
132 |
array(
|
133 |
__CLASS__,
|
134 |
+
'add_dashboard_count',
|
135 |
)
|
136 |
);
|
137 |
add_action(
|
138 |
'wp_dashboard_setup',
|
139 |
array(
|
140 |
__CLASS__,
|
141 |
+
'add_dashboard_chart',
|
142 |
)
|
143 |
);
|
144 |
|
145 |
+
} elseif ( self::_current_page( 'plugins' ) ) {
|
|
|
146 |
add_action(
|
147 |
'init',
|
148 |
array(
|
149 |
__CLASS__,
|
150 |
+
'load_plugin_lang',
|
151 |
)
|
152 |
);
|
153 |
add_filter(
|
154 |
'plugin_row_meta',
|
155 |
array(
|
156 |
__CLASS__,
|
157 |
+
'init_row_meta',
|
158 |
),
|
159 |
10,
|
160 |
2
|
161 |
);
|
162 |
add_filter(
|
163 |
+
'plugin_action_links_' . self::$_base,
|
164 |
array(
|
165 |
__CLASS__,
|
166 |
+
'init_action_links',
|
167 |
)
|
168 |
);
|
169 |
|
170 |
+
} elseif ( self::_current_page( 'options' ) ) {
|
|
|
171 |
add_action(
|
172 |
'admin_init',
|
173 |
array(
|
174 |
__CLASS__,
|
175 |
+
'load_plugin_lang',
|
176 |
)
|
177 |
);
|
178 |
add_action(
|
179 |
'admin_init',
|
180 |
array(
|
181 |
__CLASS__,
|
182 |
+
'init_plugin_sources',
|
183 |
)
|
184 |
);
|
185 |
|
186 |
+
} elseif ( self::_current_page( 'admin-post' ) ) {
|
187 |
+
require_once dirname( __FILE__ ) . '/inc/gui.class.php';
|
188 |
|
189 |
add_action(
|
190 |
'admin_post_ab_save_changes',
|
191 |
array(
|
192 |
'Antispam_Bee_GUI',
|
193 |
+
'save_changes',
|
194 |
)
|
195 |
);
|
196 |
|
197 |
+
} elseif ( self::_current_page( 'edit-comments' ) ) {
|
198 |
+
// phpcs:disable WordPress.CSRF.NonceVerification.NoNonceVerification
|
199 |
+
if ( ! empty( $_GET['comment_status'] ) && 'spam' === $_GET['comment_status'] && ! self::get_option( 'no_notice' ) ) {
|
200 |
+
// phpcs:enable WordPress.CSRF.NonceVerification.NoNonceVerification
|
201 |
+
require_once dirname( __FILE__ ) . '/inc/columns.class.php';
|
202 |
|
|
|
203 |
self::load_plugin_lang();
|
204 |
|
|
|
205 |
add_filter(
|
206 |
'manage_edit-comments_columns',
|
207 |
array(
|
208 |
'Antispam_Bee_Columns',
|
209 |
+
'register_plugin_columns',
|
210 |
)
|
211 |
);
|
212 |
add_filter(
|
213 |
'manage_comments_custom_column',
|
214 |
array(
|
215 |
'Antispam_Bee_Columns',
|
216 |
+
'print_plugin_column',
|
217 |
),
|
218 |
10,
|
219 |
2
|
220 |
);
|
221 |
add_filter(
|
222 |
+
'admin_print_styles-edit-comments.php',
|
223 |
+
array(
|
224 |
+
'Antispam_Bee_Columns',
|
225 |
+
'print_column_styles',
|
226 |
+
)
|
227 |
);
|
228 |
|
229 |
add_filter(
|
230 |
'manage_edit-comments_sortable_columns',
|
231 |
array(
|
232 |
'Antispam_Bee_Columns',
|
233 |
+
'register_sortable_columns',
|
234 |
)
|
235 |
);
|
236 |
add_action(
|
237 |
'pre_get_posts',
|
238 |
array(
|
239 |
'Antispam_Bee_Columns',
|
240 |
+
'set_orderby_query',
|
241 |
)
|
242 |
);
|
243 |
}
|
244 |
}
|
|
|
|
|
245 |
} else {
|
246 |
add_action(
|
247 |
'wp',
|
248 |
array(
|
249 |
__CLASS__,
|
250 |
+
'populate_post_id',
|
251 |
)
|
252 |
);
|
253 |
|
254 |
+
// Save IP hash, if comment is spam.
|
255 |
+
add_action(
|
256 |
+
'comment_post',
|
257 |
+
array(
|
258 |
+
__CLASS__,
|
259 |
+
'save_ip_hash',
|
260 |
+
),
|
261 |
+
10,
|
262 |
+
1
|
263 |
+
);
|
264 |
+
|
265 |
add_action(
|
266 |
'template_redirect',
|
267 |
array(
|
268 |
__CLASS__,
|
269 |
+
'prepare_comment_field',
|
270 |
)
|
271 |
);
|
272 |
add_action(
|
273 |
'init',
|
274 |
array(
|
275 |
__CLASS__,
|
276 |
+
'precheck_incoming_request',
|
277 |
)
|
278 |
);
|
279 |
add_action(
|
280 |
'preprocess_comment',
|
281 |
array(
|
282 |
__CLASS__,
|
283 |
+
'handle_incoming_request',
|
284 |
),
|
285 |
1
|
286 |
);
|
288 |
'antispam_bee_count',
|
289 |
array(
|
290 |
__CLASS__,
|
291 |
+
'the_spam_count',
|
292 |
)
|
293 |
);
|
294 |
}
|
296 |
|
297 |
|
298 |
|
299 |
+
/*
|
300 |
+
* ############################
|
301 |
+
* ######## INSTALL #########
|
302 |
+
* ############################
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
303 |
*/
|
304 |
|
305 |
+
/**
|
306 |
+
* Action during the activation of the Plugins
|
307 |
+
*
|
308 |
+
* @since 0.1
|
309 |
+
* @change 2.4
|
310 |
+
*/
|
311 |
+
public static function activate() {
|
312 |
add_option(
|
313 |
'antispam_bee',
|
314 |
array(),
|
316 |
'no'
|
317 |
);
|
318 |
|
319 |
+
if ( self::get_option( 'cronjob_enable' ) ) {
|
|
|
320 |
self::init_scheduled_hook();
|
321 |
}
|
322 |
}
|
323 |
|
324 |
|
325 |
/**
|
326 |
+
* Action to deactivate the plugin
|
327 |
+
*
|
328 |
+
* @since 0.1
|
329 |
+
* @change 2.4
|
330 |
+
*/
|
331 |
+
public static function deactivate() {
|
|
|
|
|
332 |
self::clear_scheduled_hook();
|
333 |
}
|
334 |
|
335 |
|
336 |
/**
|
337 |
+
* Action deleting the plugin
|
338 |
+
*
|
339 |
+
* @since 2.4
|
340 |
+
* @change 2.4
|
341 |
+
*/
|
342 |
+
public static function uninstall() {
|
343 |
+
if ( ! self::get_option( 'delete_data_on_uninstall' ) ) {
|
344 |
+
return;
|
345 |
+
}
|
346 |
global $wpdb;
|
347 |
|
348 |
+
delete_option( 'antispam_bee' );
|
349 |
+
$wpdb->query( 'OPTIMIZE TABLE `' . $wpdb->options . '`' );
|
350 |
|
351 |
+
//phpcs:disable WordPress.WP.PreparedSQL.NotPrepared
|
352 |
+
$sql = 'delete from `' . $wpdb->commentmeta . '` where `meta_key` IN ("antispam_bee_iphash", "antispam_bee_reason")';
|
353 |
+
$wpdb->query( $sql );
|
354 |
+
//phpcs:enable WordPress.WP.PreparedSQL.NotPrepared
|
355 |
}
|
356 |
|
357 |
|
358 |
|
359 |
+
/*
|
360 |
+
* ############################
|
361 |
+
* ######## INTERNAL ########
|
362 |
+
* ############################
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
363 |
*/
|
364 |
|
365 |
+
/**
|
366 |
+
* Initialization of the internal variables
|
367 |
+
*
|
368 |
+
* @since 2.4
|
369 |
+
* @change 2.7.0
|
370 |
+
*/
|
371 |
+
private static function _init_internal_vars() {
|
372 |
+
self::$_base = plugin_basename( __FILE__ );
|
373 |
|
374 |
+
$salt = defined( 'NONCE_SALT' ) ? NONCE_SALT : ABSPATH;
|
375 |
self::$_salt = substr( sha1( $salt ), 0, 10 );
|
376 |
|
377 |
self::$defaults = array(
|
378 |
'options' => array(
|
379 |
+
'advanced_check' => 1,
|
380 |
+
'regexp_check' => 1,
|
381 |
+
'spam_ip' => 1,
|
382 |
+
'already_commented' => 1,
|
383 |
+
'gravatar_check' => 0,
|
384 |
+
'time_check' => 0,
|
385 |
+
'ignore_pings' => 0,
|
386 |
+
'always_allowed' => 0,
|
387 |
+
|
388 |
+
'dashboard_chart' => 0,
|
389 |
+
'dashboard_count' => 0,
|
390 |
+
|
391 |
+
'country_code' => 0,
|
392 |
+
'country_black' => '',
|
393 |
+
'country_white' => '',
|
394 |
+
|
395 |
+
'translate_api' => 0,
|
396 |
+
'translate_lang' => array(),
|
397 |
+
|
398 |
+
'bbcode_check' => 1,
|
399 |
+
|
400 |
+
'flag_spam' => 1,
|
401 |
+
'email_notify' => 0,
|
402 |
+
'no_notice' => 0,
|
403 |
+
'cronjob_enable' => 0,
|
404 |
+
'cronjob_interval' => 0,
|
405 |
+
|
406 |
+
'ignore_filter' => 0,
|
407 |
+
'ignore_type' => 0,
|
408 |
+
|
409 |
+
'reasons_enable' => 0,
|
410 |
+
'ignore_reasons' => array(),
|
411 |
+
|
412 |
+
'delete_data_on_uninstall' => 1,
|
|
|
413 |
),
|
414 |
'reasons' => array(
|
415 |
+
'css' => esc_attr__( 'Honeypot', 'antispam-bee' ),
|
416 |
+
'time' => esc_attr__( 'Comment time', 'antispam-bee' ),
|
417 |
+
'empty' => esc_attr__( 'Empty Data', 'antispam-bee' ),
|
418 |
+
'server' => esc_attr__( 'Fake IP', 'antispam-bee' ),
|
419 |
+
'localdb' => esc_attr__( 'Local DB Spam', 'antispam-bee' ),
|
420 |
+
'country' => esc_attr__( 'Country Check', 'antispam-bee' ),
|
421 |
+
'bbcode' => esc_attr__( 'BBCode', 'antispam-bee' ),
|
422 |
+
'lang' => esc_attr__( 'Comment Language', 'antispam-bee' ),
|
423 |
+
'regexp' => esc_attr__( 'Regular Expression', 'antispam-bee' ),
|
424 |
+
'title_is_name' => esc_attr__( 'Identical Post title and blog title', 'antispam-bee' ),
|
425 |
+
),
|
426 |
);
|
427 |
}
|
428 |
|
|
|
429 |
/**
|
430 |
+
* Check and return an array key
|
431 |
+
*
|
432 |
+
* @since 2.4.2
|
433 |
+
* @change 2.4.2
|
434 |
+
*
|
435 |
+
* @param array $array Array with values.
|
436 |
+
* @param string $key Name of the key.
|
437 |
+
* @return mixed Value of the requested key.
|
438 |
+
*/
|
439 |
+
public static function get_key( $array, $key ) {
|
440 |
+
if ( empty( $array ) || empty( $key ) || empty( $array[ $key ] ) ) {
|
|
|
|
|
441 |
return null;
|
442 |
}
|
443 |
|
444 |
+
return $array[ $key ];
|
445 |
}
|
446 |
|
447 |
|
448 |
/**
|
449 |
+
* Localization of the admin pages
|
450 |
+
*
|
451 |
+
* @since 0.1
|
452 |
+
* @change 2.4
|
453 |
+
*
|
454 |
+
* @param string $page Mark the page.
|
455 |
+
* @return boolean True on success.
|
456 |
+
*/
|
457 |
+
private static function _current_page( $page ) {
|
458 |
+
// phpcs:disable WordPress.CSRF.NonceVerification.NoNonceVerification
|
459 |
+
switch ( $page ) {
|
|
|
460 |
case 'dashboard':
|
461 |
+
return ( empty( $GLOBALS['pagenow'] ) || ( ! empty( $GLOBALS['pagenow'] ) && 'index.php' === $GLOBALS['pagenow'] ) );
|
462 |
|
463 |
case 'options':
|
464 |
+
return ( ! empty( $_GET['page'] ) && 'antispam_bee' === $_GET['page'] );
|
465 |
|
466 |
case 'plugins':
|
467 |
+
return ( ! empty( $GLOBALS['pagenow'] ) && 'plugins.php' === $GLOBALS['pagenow'] );
|
468 |
|
469 |
case 'admin-post':
|
470 |
+
return ( ! empty( $GLOBALS['pagenow'] ) && 'admin-post.php' === $GLOBALS['pagenow'] );
|
471 |
|
472 |
case 'edit-comments':
|
473 |
+
return ( ! empty( $GLOBALS['pagenow'] ) && 'edit-comments.php' === $GLOBALS['pagenow'] );
|
474 |
|
475 |
default:
|
476 |
return false;
|
477 |
}
|
478 |
+
// phpcs:enable WordPress.CSRF.NonceVerification.NoNonceVerification
|
479 |
}
|
480 |
|
481 |
|
482 |
/**
|
483 |
+
* Integration of the localization file
|
484 |
+
*
|
485 |
+
* @since 0.1
|
486 |
+
* @change 2.4
|
487 |
+
*/
|
488 |
+
public static function load_plugin_lang() {
|
|
|
|
|
489 |
load_plugin_textdomain(
|
490 |
'antispam-bee'
|
491 |
);
|
493 |
|
494 |
|
495 |
/**
|
496 |
+
* Add the link to the settings
|
497 |
+
*
|
498 |
+
* @since 1.1
|
499 |
+
* @change 1.1
|
500 |
+
*
|
501 |
+
* @param array $data The action link array.
|
502 |
+
* @return array $data The action link array.
|
503 |
+
*/
|
504 |
+
public static function init_action_links( $data ) {
|
505 |
+
if ( ! current_user_can( 'manage_options' ) ) {
|
506 |
return $data;
|
507 |
}
|
508 |
|
513 |
'<a href="%s">%s</a>',
|
514 |
add_query_arg(
|
515 |
array(
|
516 |
+
'page' => 'antispam_bee',
|
517 |
),
|
518 |
+
admin_url( 'options-general.php' )
|
519 |
),
|
520 |
+
esc_attr__( 'Settings', 'antispam-bee' )
|
521 |
+
),
|
522 |
)
|
523 |
);
|
524 |
}
|
525 |
|
|
|
526 |
/**
|
527 |
+
* Meta links of the plugin
|
528 |
+
*
|
529 |
+
* @since 0.1
|
530 |
+
* @change 2.6.2
|
531 |
+
*
|
532 |
+
* @param array $input Existing links.
|
533 |
+
* @param string $file Current page.
|
534 |
+
* @return array $data Modified links.
|
535 |
+
*/
|
536 |
+
public static function init_row_meta( $input, $file ) {
|
537 |
+
if ( $file !== self::$_base ) {
|
|
|
|
|
|
|
538 |
return $input;
|
539 |
}
|
540 |
|
547 |
);
|
548 |
}
|
549 |
|
550 |
+
/*
|
551 |
+
* ############################
|
552 |
+
* ####### RESOURCES ########
|
553 |
+
* ############################
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
554 |
*/
|
555 |
|
556 |
+
/**
|
557 |
+
* Registration of resources (CSS & JS)
|
558 |
+
*
|
559 |
+
* @since 1.6
|
560 |
+
* @change 2.4.5
|
561 |
+
*/
|
562 |
+
public static function init_plugin_sources() {
|
563 |
+
$plugin = get_plugin_data( __FILE__ );
|
564 |
|
|
|
565 |
wp_register_script(
|
566 |
'ab_script',
|
567 |
+
plugins_url( 'js/scripts.min.js', __FILE__ ),
|
568 |
+
array( 'jquery' ),
|
569 |
$plugin['Version']
|
570 |
);
|
571 |
|
|
|
572 |
wp_register_style(
|
573 |
'ab_style',
|
574 |
+
plugins_url( 'css/styles.min.css', __FILE__ ),
|
575 |
array( 'dashicons' ),
|
576 |
$plugin['Version']
|
577 |
);
|
579 |
|
580 |
|
581 |
/**
|
582 |
+
* Initialization of the option page
|
583 |
+
*
|
584 |
+
* @since 0.1
|
585 |
+
* @change 2.4.3
|
586 |
+
*/
|
587 |
+
public static function add_sidebar_menu() {
|
|
|
|
|
|
|
588 |
$page = add_options_page(
|
589 |
'Antispam Bee',
|
590 |
'Antispam Bee',
|
592 |
'antispam_bee',
|
593 |
array(
|
594 |
'Antispam_Bee_GUI',
|
595 |
+
'options_page',
|
596 |
)
|
597 |
);
|
598 |
|
|
|
599 |
add_action(
|
600 |
'admin_print_scripts-' . $page,
|
601 |
array(
|
602 |
__CLASS__,
|
603 |
+
'add_options_script',
|
604 |
)
|
605 |
);
|
606 |
|
|
|
607 |
add_action(
|
608 |
'admin_print_styles-' . $page,
|
609 |
array(
|
610 |
__CLASS__,
|
611 |
+
'add_options_style',
|
612 |
)
|
613 |
);
|
614 |
|
|
|
615 |
add_action(
|
616 |
+
'load-' . $page,
|
617 |
array(
|
618 |
__CLASS__,
|
619 |
+
'init_options_page',
|
620 |
)
|
621 |
);
|
622 |
}
|
623 |
|
624 |
|
625 |
/**
|
626 |
+
* Initialization of JavaScript
|
627 |
+
*
|
628 |
+
* @since 1.6
|
629 |
+
* @change 2.4
|
630 |
+
*/
|
631 |
+
public static function add_options_script() {
|
632 |
+
wp_enqueue_script( 'ab_script' );
|
|
|
|
|
633 |
}
|
634 |
|
635 |
|
636 |
/**
|
637 |
+
* Initialization of Stylesheets
|
638 |
+
*
|
639 |
+
* @since 1.6
|
640 |
+
* @change 2.4
|
641 |
+
*/
|
642 |
+
public static function add_options_style() {
|
643 |
+
wp_enqueue_style( 'ab_style' );
|
|
|
|
|
644 |
}
|
645 |
|
646 |
|
647 |
/**
|
648 |
+
* Integration of the GUI
|
649 |
+
*
|
650 |
+
* @since 2.4
|
651 |
+
* @change 2.4
|
652 |
+
*/
|
653 |
+
public static function init_options_page() {
|
654 |
+
require_once dirname( __FILE__ ) . '/inc/gui.class.php';
|
|
|
|
|
655 |
}
|
656 |
|
657 |
|
658 |
|
659 |
+
/*
|
660 |
+
* ############################
|
661 |
+
* ####### DASHBOARD ########
|
662 |
+
* ############################
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
663 |
*/
|
664 |
|
665 |
+
/**
|
666 |
+
* Display the spam counter on the dashboard
|
667 |
+
*
|
668 |
+
* @since 0.1
|
669 |
+
* @change 2.6.5
|
670 |
+
*
|
671 |
+
* @param array $items Initial array with dashboard items.
|
672 |
+
* @return array $items Merged array with dashboard items.
|
673 |
+
*/
|
674 |
+
public static function add_dashboard_count( $items = array() ) {
|
675 |
+
if ( ! current_user_can( 'manage_options' ) || ! self::get_option( 'dashboard_count' ) ) {
|
676 |
+
return $items;
|
677 |
}
|
678 |
|
679 |
+
echo '<style>#dashboard_right_now .ab-count:before {content: "\f117"}</style>';
|
|
|
680 |
|
681 |
+
$items[] = '<span class="ab-count">' . esc_html(
|
682 |
+
sprintf(
|
683 |
+
// translators: The number of spam comments Antispam Bee blocked so far.
|
684 |
+
__( '%d Blocked', 'antispam-bee' ),
|
685 |
+
self::_get_spam_count()
|
686 |
+
)
|
687 |
) . '</span>';
|
688 |
|
689 |
+
return $items;
|
690 |
}
|
691 |
|
|
|
692 |
/**
|
693 |
+
* Initialize the dashboard chart
|
694 |
+
*
|
695 |
+
* @since 1.9
|
696 |
+
* @change 2.5.6
|
697 |
+
*/
|
698 |
+
public static function add_dashboard_chart() {
|
|
|
|
|
699 |
if ( ! current_user_can( 'publish_posts' ) || ! self::get_option( 'dashboard_chart' ) ) {
|
700 |
return;
|
701 |
}
|
702 |
|
|
|
703 |
wp_add_dashboard_widget(
|
704 |
'ab_widget',
|
705 |
'Antispam Bee',
|
706 |
array(
|
707 |
__CLASS__,
|
708 |
+
'show_spam_chart',
|
709 |
)
|
710 |
);
|
711 |
|
|
|
712 |
add_action(
|
713 |
'admin_head',
|
714 |
array(
|
715 |
__CLASS__,
|
716 |
+
'add_dashboard_style',
|
717 |
)
|
718 |
);
|
719 |
}
|
720 |
|
|
|
721 |
/**
|
722 |
+
* Print dashboard styles
|
723 |
+
*
|
724 |
+
* @since 1.9.0
|
725 |
+
* @change 2.5.8
|
726 |
+
*/
|
727 |
+
public static function add_dashboard_style() {
|
728 |
+
$plugin = get_plugin_data( __FILE__ );
|
|
|
|
|
|
|
729 |
|
|
|
730 |
wp_register_style(
|
731 |
'ab_chart',
|
732 |
+
plugins_url( 'css/dashboard.min.css', __FILE__ ),
|
733 |
array(),
|
734 |
$plugin['Version']
|
735 |
);
|
736 |
|
737 |
+
wp_print_styles( 'ab_chart' );
|
|
|
738 |
}
|
739 |
|
740 |
|
741 |
/**
|
742 |
+
* Print dashboard scripts
|
743 |
+
*
|
744 |
+
* @since 1.9.0
|
745 |
+
* @change 2.5.8
|
746 |
+
*/
|
747 |
public static function add_dashboard_script() {
|
748 |
+
if ( ! self::get_option( 'daily_stats' ) ) {
|
|
|
749 |
return;
|
750 |
}
|
751 |
|
752 |
+
$plugin = get_plugin_data( __FILE__ );
|
|
|
753 |
|
|
|
754 |
wp_enqueue_script(
|
755 |
'raphael',
|
756 |
plugins_url( 'js/raphael.min.js', __FILE__ ),
|
776 |
);
|
777 |
}
|
778 |
|
|
|
779 |
/**
|
780 |
+
* Print dashboard html
|
781 |
+
*
|
782 |
+
* @since 1.9.0
|
783 |
+
* @change 2.5.8
|
784 |
+
*/
|
785 |
+
public static function show_spam_chart() {
|
786 |
+
$items = (array) self::get_option( 'daily_stats' );
|
|
|
|
|
|
|
787 |
|
788 |
+
if ( empty( $items ) ) {
|
|
|
789 |
echo sprintf(
|
790 |
'<div id="ab_chart"><p>%s</p></div>',
|
791 |
+
esc_html__( 'No data available.', 'antispam-bee' )
|
792 |
);
|
793 |
|
794 |
return;
|
795 |
}
|
796 |
|
|
|
797 |
self::add_dashboard_script();
|
798 |
|
799 |
+
ksort( $items, SORT_NUMERIC );
|
|
|
800 |
|
|
|
801 |
$html = "<table id=ab_chart_data>\n";
|
802 |
|
|
|
|
|
803 |
$html .= "<tfoot><tr>\n";
|
804 |
+
foreach ( $items as $date => $count ) {
|
805 |
+
$html .= '<th>' . $date . "</th>\n";
|
806 |
}
|
807 |
$html .= "</tr></tfoot>\n";
|
808 |
|
|
|
809 |
$html .= "<tbody><tr>\n";
|
810 |
+
foreach ( $items as $date => $count ) {
|
811 |
+
$html .= '<td>' . (int) $count . "</td>\n";
|
812 |
}
|
813 |
$html .= "</tr></tbody>\n";
|
814 |
|
|
|
|
|
815 |
$html .= "</table>\n";
|
816 |
|
817 |
+
echo wp_kses_post( '<div id="ab_chart">' . $html . '</div>' );
|
|
|
818 |
}
|
819 |
|
820 |
+
/*
|
821 |
+
* ############################
|
822 |
+
* ######## OPTIONS #########
|
823 |
+
* ############################
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
824 |
*/
|
825 |
|
826 |
+
/**
|
827 |
+
* Get all plugin options
|
828 |
+
*
|
829 |
+
* @since 2.4
|
830 |
+
* @change 2.6.1
|
831 |
+
*
|
832 |
+
* @return array $options Array with option fields.
|
833 |
+
*/
|
834 |
+
public static function get_options() {
|
835 |
+
$options = wp_cache_get( 'antispam_bee' );
|
836 |
+
if ( ! $options ) {
|
837 |
wp_cache_set(
|
838 |
'antispam_bee',
|
839 |
+
$options = get_option( 'antispam_bee' )
|
840 |
);
|
841 |
}
|
842 |
|
846 |
);
|
847 |
}
|
848 |
|
|
|
849 |
/**
|
850 |
+
* Get single option field
|
851 |
+
*
|
852 |
+
* @since 0.1
|
853 |
+
* @change 2.4.2
|
854 |
+
*
|
855 |
+
* @param string $field Field name.
|
856 |
+
* @return mixed Field value.
|
857 |
+
*/
|
858 |
+
public static function get_option( $field ) {
|
|
|
|
|
|
|
859 |
$options = self::get_options();
|
860 |
|
861 |
+
return self::get_key( $options, $field );
|
862 |
}
|
863 |
|
864 |
|
865 |
/**
|
866 |
+
* Update single option field
|
867 |
+
*
|
868 |
+
* @since 0.1
|
869 |
+
* @change 2.4
|
870 |
+
*
|
871 |
+
* @param string $field Field name.
|
872 |
+
* @param mixed $value The Field value.
|
873 |
+
*/
|
874 |
+
private static function _update_option( $field, $value ) {
|
|
|
|
|
875 |
self::update_options(
|
876 |
array(
|
877 |
+
$field => $value,
|
878 |
)
|
879 |
);
|
880 |
}
|
881 |
|
882 |
|
883 |
/**
|
884 |
+
* Update multiple option fields
|
885 |
+
*
|
886 |
+
* @since 0.1
|
887 |
+
* @change 2.6.1
|
888 |
+
*
|
889 |
+
* @param array $data Array with plugin option fields.
|
890 |
+
*/
|
891 |
+
public static function update_options( $data ) {
|
892 |
+
$options = get_option( 'antispam_bee' );
|
|
|
|
|
|
|
893 |
|
894 |
+
if ( is_array( $options ) ) {
|
|
|
895 |
$options = array_merge(
|
896 |
$options,
|
897 |
$data
|
898 |
);
|
899 |
+
} else {
|
|
|
900 |
$options = $data;
|
901 |
}
|
902 |
|
|
|
903 |
update_option(
|
904 |
'antispam_bee',
|
905 |
$options
|
906 |
);
|
907 |
|
|
|
908 |
wp_cache_set(
|
909 |
'antispam_bee',
|
910 |
$options
|
913 |
|
914 |
|
915 |
|
916 |
+
/*
|
917 |
+
* ############################
|
918 |
+
* ######## CRONJOBS ########
|
919 |
+
* ############################
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
920 |
*/
|
921 |
|
922 |
+
/**
|
923 |
+
* Execution of the daily cronjobs
|
924 |
+
*
|
925 |
+
* @since 0.1
|
926 |
+
* @change 2.4
|
927 |
+
*/
|
928 |
+
public static function start_daily_cronjob() {
|
929 |
+
if ( ! self::get_option( 'cronjob_enable' ) ) {
|
930 |
return;
|
931 |
}
|
932 |
|
|
|
933 |
self::_update_option(
|
934 |
'cronjob_timestamp',
|
935 |
time()
|
936 |
);
|
937 |
|
|
|
938 |
self::_delete_old_spam();
|
939 |
}
|
940 |
|
941 |
|
942 |
/**
|
943 |
+
* Delete old spam comments
|
944 |
+
*
|
945 |
+
* @since 0.1
|
946 |
+
* @change 2.4
|
947 |
+
*/
|
948 |
+
private static function _delete_old_spam() {
|
949 |
+
$days = (int) self::get_option( 'cronjob_interval' );
|
|
|
|
|
|
|
950 |
|
951 |
+
if ( empty( $days ) ) {
|
|
|
952 |
return false;
|
953 |
}
|
954 |
|
|
|
955 |
global $wpdb;
|
956 |
|
|
|
957 |
$wpdb->query(
|
958 |
$wpdb->prepare(
|
959 |
"DELETE FROM `$wpdb->comments` WHERE `comment_approved` = 'spam' AND SUBDATE(NOW(), %d) > comment_date_gmt",
|
961 |
)
|
962 |
);
|
963 |
|
964 |
+
$wpdb->query( "OPTIMIZE TABLE `$wpdb->comments`" );
|
|
|
965 |
}
|
966 |
|
967 |
|
968 |
/**
|
969 |
+
* Initialization of the cronjobs
|
970 |
+
*
|
971 |
+
* @since 0.1
|
972 |
+
* @change 2.4
|
973 |
+
*/
|
974 |
+
public static function init_scheduled_hook() {
|
975 |
+
if ( ! wp_next_scheduled( 'antispam_bee_daily_cronjob' ) ) {
|
|
|
|
|
976 |
wp_schedule_event(
|
977 |
time(),
|
978 |
'daily',
|
983 |
|
984 |
|
985 |
/**
|
986 |
+
* Deletion of the cronjobs
|
987 |
+
*
|
988 |
+
* @since 0.1
|
989 |
+
* @change 2.4
|
990 |
+
*/
|
991 |
+
public static function clear_scheduled_hook() {
|
992 |
+
if ( wp_next_scheduled( 'antispam_bee_daily_cronjob' ) ) {
|
993 |
+
wp_clear_scheduled_hook( 'antispam_bee_daily_cronjob' );
|
|
|
|
|
994 |
}
|
995 |
}
|
996 |
|
997 |
|
998 |
|
999 |
+
/*
|
1000 |
+
* ############################
|
1001 |
+
* ###### SPAM CHECK ########
|
1002 |
+
* ############################
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1003 |
*/
|
1004 |
|
1005 |
+
/**
|
1006 |
+
* Check POST values
|
1007 |
+
*
|
1008 |
+
* @since 0.1
|
1009 |
+
* @change 2.6.3
|
1010 |
+
*/
|
1011 |
+
public static function precheck_incoming_request() {
|
1012 |
+
// phpcs:disable WordPress.CSRF.NonceVerification.NoNonceVerification
|
1013 |
+
if ( is_feed() || is_trackback() || empty( $_POST ) || self::_is_mobile() ) {
|
1014 |
return;
|
1015 |
}
|
1016 |
|
1017 |
+
$request_uri = self::get_key( $_SERVER, 'REQUEST_URI' );
|
1018 |
+
$request_path = self::parse_url( $request_uri, 'path' );
|
|
|
1019 |
|
1020 |
+
if ( strpos( $request_path, 'wp-comments-post.php' ) === false ) {
|
|
|
1021 |
return;
|
1022 |
}
|
1023 |
|
1024 |
+
$post_id = (int) self::get_key( $_POST, 'comment_post_ID' );
|
|
|
1025 |
$hidden_field = self::get_key( $_POST, 'comment' );
|
1026 |
$plugin_field = self::get_key( $_POST, self::get_secret_name_for_post( $post_id ) );
|
1027 |
|
1028 |
+
if ( empty( $hidden_field ) && ! empty( $plugin_field ) ) {
|
|
|
1029 |
$_POST['comment'] = $plugin_field;
|
1030 |
unset( $_POST[ self::get_secret_name_for_post( $post_id ) ] );
|
1031 |
} else {
|
1032 |
$_POST['ab_spam__hidden_field'] = 1;
|
1033 |
}
|
1034 |
+
// phpcs:enable WordPress.CSRF.NonceVerification.NoNonceVerification
|
1035 |
}
|
1036 |
|
1037 |
|
1038 |
/**
|
1039 |
+
* Check incoming requests for spam
|
1040 |
+
*
|
1041 |
+
* @since 0.1
|
1042 |
+
* @change 2.6.3
|
1043 |
+
*
|
1044 |
+
* @param array $comment Untreated comment.
|
1045 |
+
* @return array $comment Treated comment.
|
1046 |
+
*/
|
1047 |
+
public static function handle_incoming_request( $comment ) {
|
|
|
|
|
|
|
1048 |
$comment['comment_author_IP'] = self::get_client_ip();
|
1049 |
|
1050 |
+
$request_uri = self::get_key( $_SERVER, 'REQUEST_URI' );
|
1051 |
+
$request_path = self::parse_url( $request_uri, 'path' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1052 |
|
1053 |
+
if ( empty( $request_path ) ) {
|
|
|
1054 |
return self::_handle_spam_request(
|
1055 |
$comment,
|
1056 |
'empty'
|
1057 |
);
|
1058 |
}
|
1059 |
|
|
|
1060 |
$ping = array(
|
1061 |
+
'types' => array( 'pingback', 'trackback', 'pings' ),
|
1062 |
+
'allowed' => ! self::get_option( 'ignore_pings' ),
|
1063 |
);
|
1064 |
|
1065 |
+
// phpcs:disable WordPress.CSRF.NonceVerification.NoNonceVerification
|
1066 |
+
// Everybody can post.
|
1067 |
+
if ( strpos( $request_path, 'wp-comments-post.php' ) !== false && ! empty( $_POST ) ) {
|
1068 |
+
// phpcs:enable WordPress.CSRF.NonceVerification.NoNonceVerification
|
1069 |
+
$status = self::_verify_comment_request( $comment );
|
1070 |
|
1071 |
+
if ( ! empty( $status['reason'] ) ) {
|
|
|
1072 |
return self::_handle_spam_request(
|
1073 |
$comment,
|
1074 |
$status['reason']
|
1075 |
);
|
1076 |
}
|
1077 |
+
} elseif ( in_array( self::get_key( $comment, 'comment_type' ), $ping['types'], true ) && $ping['allowed'] ) {
|
1078 |
+
$status = self::_verify_trackback_request( $comment );
|
1079 |
|
1080 |
+
if ( ! empty( $status['reason'] ) ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
1081 |
return self::_handle_spam_request(
|
1082 |
$comment,
|
1083 |
$status['reason'],
|
1091 |
|
1092 |
|
1093 |
/**
|
1094 |
+
* Prepares the replacement of the comment field
|
1095 |
+
*
|
1096 |
+
* @since 0.1
|
1097 |
+
* @change 2.4
|
1098 |
+
*/
|
1099 |
+
public static function prepare_comment_field() {
|
1100 |
+
if ( is_feed() || is_trackback() || is_robots() || self::_is_mobile() ) {
|
|
|
|
|
|
|
1101 |
return;
|
1102 |
}
|
1103 |
|
1104 |
+
if ( ! is_singular() && ! self::get_option( 'always_allowed' ) ) {
|
|
|
1105 |
return;
|
1106 |
}
|
1107 |
|
|
|
1108 |
ob_start(
|
1109 |
array(
|
1110 |
'Antispam_Bee',
|
1111 |
+
'replace_comment_field',
|
1112 |
)
|
1113 |
);
|
1114 |
}
|
1115 |
|
1116 |
|
1117 |
/**
|
1118 |
+
* Replaces the comment field
|
1119 |
+
*
|
1120 |
+
* @since 2.4
|
1121 |
+
* @change 2.6.4
|
1122 |
+
*
|
1123 |
+
* @param string $data HTML code of the website.
|
1124 |
+
* @return string Treated HTML code.
|
1125 |
+
*/
|
1126 |
+
public static function replace_comment_field( $data ) {
|
1127 |
+
if ( empty( $data ) ) {
|
|
|
|
|
|
|
1128 |
return;
|
1129 |
}
|
1130 |
|
1131 |
+
if ( ! preg_match( '#<textarea.+?name=["\']comment["\']#s', $data ) ) {
|
|
|
1132 |
return $data;
|
1133 |
}
|
1134 |
|
|
|
1135 |
return preg_replace_callback(
|
1136 |
'/(?P<all> (?# match the whole textarea tag )
|
1137 |
<textarea (?# the opening of the textarea and some optional attributes )
|
1155 |
)/x',
|
1156 |
array( 'Antispam_Bee', 'replace_comment_field_callback' ),
|
1157 |
$data,
|
1158 |
+
-1
|
1159 |
);
|
1160 |
}
|
1161 |
|
1169 |
* @return string The modified content string.
|
1170 |
*/
|
1171 |
public static function replace_comment_field_callback( $matches ) {
|
1172 |
+
if ( self::get_option( 'time_check' ) ) {
|
|
|
1173 |
$init_time_field = sprintf(
|
1174 |
'<input type="hidden" name="ab_init_time" value="%d" />',
|
1175 |
time()
|
1182 |
|
1183 |
$id_script = '';
|
1184 |
if ( ! empty( $matches['id1'] ) || ! empty( $matches['id2'] ) ) {
|
1185 |
+
$output .= 'id="' . self::get_secret_id_for_post( self::$_current_post_id ) . '" ';
|
1186 |
$id_script = '<script type="text/javascript">document.getElementById("comment").setAttribute( "id", "' . esc_js( md5( time() ) ) . '" );document.getElementById("' . esc_js( self::get_secret_id_for_post( self::$_current_post_id ) ) . '").setAttribute( "id", "comment" );</script>';
|
1187 |
}
|
1188 |
|
1199 |
|
1200 |
|
1201 |
/**
|
1202 |
+
* Check the trackbacks
|
1203 |
+
*
|
1204 |
+
* @since 2.4
|
1205 |
+
* @change 2.7.0
|
1206 |
+
*
|
1207 |
+
* @param array $comment Trackback data.
|
1208 |
+
* @return array Array with suspected reason.
|
1209 |
+
*/
|
1210 |
+
private static function _verify_trackback_request( $comment ) {
|
1211 |
+
$ip = self::get_key( $comment, 'comment_author_IP' );
|
1212 |
+
$url = self::get_key( $comment, 'comment_author_url' );
|
1213 |
+
$body = self::get_key( $comment, 'comment_content' );
|
1214 |
+
$post_id = self::get_key( $comment, 'comment_post_ID' );
|
1215 |
+
$type = self::get_key( $comment, 'comment_type' );
|
1216 |
+
$blog_name = self::get_key( $comment, 'comment_author' );
|
1217 |
+
|
1218 |
+
if ( empty( $url ) || empty( $body ) ) {
|
1219 |
+
return array(
|
1220 |
+
'reason' => 'empty',
|
1221 |
+
);
|
1222 |
+
}
|
1223 |
|
1224 |
+
if ( empty( $ip ) ) {
|
|
|
1225 |
return array(
|
1226 |
+
'reason' => 'empty',
|
1227 |
);
|
1228 |
}
|
1229 |
|
1230 |
+
if ( 'pingback' === $type && self::_pingback_from_myself( $url, $post_id ) ) {
|
1231 |
+
return;
|
1232 |
+
}
|
1233 |
+
|
1234 |
+
if ( self::is_trackback_post_title_blog_name_spam( $body, $blog_name ) ) {
|
1235 |
return array(
|
1236 |
+
'reason' => 'title_is_name',
|
1237 |
);
|
1238 |
}
|
1239 |
|
|
|
1240 |
$options = self::get_options();
|
1241 |
|
1242 |
+
if ( $options['bbcode_check'] && self::_is_bbcode_spam( $body ) ) {
|
|
|
1243 |
return array(
|
1244 |
+
'reason' => 'bbcode',
|
1245 |
);
|
1246 |
}
|
1247 |
|
1248 |
+
if ( $options['advanced_check'] && self::_is_fake_ip( $ip, self::parse_url( $url, 'host' ) ) ) {
|
|
|
1249 |
return array(
|
1250 |
+
'reason' => 'server',
|
1251 |
);
|
1252 |
}
|
1253 |
|
1254 |
+
if ( $options['spam_ip'] && self::_is_db_spam( $ip, $url ) ) {
|
|
|
1255 |
return array(
|
1256 |
+
'reason' => 'localdb',
|
1257 |
);
|
1258 |
}
|
1259 |
|
1260 |
+
if ( $options['country_code'] && self::_is_country_spam( $ip ) ) {
|
|
|
1261 |
return array(
|
1262 |
+
'reason' => 'country',
|
1263 |
);
|
1264 |
}
|
1265 |
|
1266 |
+
if ( $options['translate_api'] && self::_is_lang_spam( $body ) ) {
|
|
|
1267 |
return array(
|
1268 |
+
'reason' => 'lang',
|
1269 |
);
|
1270 |
}
|
|
|
1271 |
|
1272 |
+
if ( $options['regexp_check'] && self::_is_regexp_spam(
|
1273 |
+
array(
|
1274 |
+
'ip' => $ip,
|
1275 |
+
'rawurl' => $url,
|
1276 |
+
'host' => self::parse_url( $url, 'host' ),
|
1277 |
+
'body' => $body,
|
1278 |
+
'email' => '',
|
1279 |
+
'author' => '',
|
1280 |
+
)
|
1281 |
+
) ) {
|
1282 |
+
return array(
|
1283 |
+
'reason' => 'regexp',
|
1284 |
+
);
|
1285 |
+
}
|
1286 |
+
}
|
1287 |
|
1288 |
/**
|
1289 |
+
* Check, if I pinged myself.
|
1290 |
+
*
|
1291 |
+
* @since 2.8.2
|
1292 |
+
*
|
1293 |
+
* @param string $url The URL from where the ping came.
|
1294 |
+
* @param int $target_post_id The post ID which has been pinged.
|
1295 |
+
*
|
1296 |
+
* @return bool
|
1297 |
+
*/
|
1298 |
+
private static function _pingback_from_myself( $url, $target_post_id ) {
|
1299 |
+
|
1300 |
+
if ( 0 !== strpos( $url, home_url() ) ) {
|
1301 |
+
return false;
|
1302 |
+
}
|
1303 |
+
|
1304 |
+
$original_post_id = (int) url_to_postid( $url );
|
1305 |
+
if ( ! $original_post_id ) {
|
1306 |
+
return false;
|
1307 |
+
}
|
1308 |
+
|
1309 |
+
$post = get_post( $original_post_id );
|
1310 |
+
if ( ! $post ) {
|
1311 |
+
return false;
|
1312 |
+
}
|
1313 |
|
1314 |
+
$urls = wp_extract_urls( $post->post_content );
|
1315 |
+
$url_to_find = get_permalink( $target_post_id );
|
1316 |
+
if ( ! $url_to_find ) {
|
1317 |
+
return false;
|
1318 |
+
}
|
1319 |
+
foreach ( $urls as $url ) {
|
1320 |
+
if ( strpos( $url, $url_to_find ) === 0 ) {
|
1321 |
+
return true;
|
1322 |
+
}
|
1323 |
+
}
|
1324 |
+
return false;
|
1325 |
+
}
|
1326 |
+
|
1327 |
+
/**
|
1328 |
+
* Check the comment
|
1329 |
+
*
|
1330 |
+
* @since 2.4
|
1331 |
+
* @change 2.7.0
|
1332 |
+
*
|
1333 |
+
* @param array $comment Data of the comment.
|
1334 |
+
* @return array|void Array with suspected reason
|
1335 |
+
*/
|
1336 |
+
private static function _verify_comment_request( $comment ) {
|
1337 |
+
$ip = self::get_key( $comment, 'comment_author_IP' );
|
1338 |
+
$url = self::get_key( $comment, 'comment_author_url' );
|
1339 |
+
$body = self::get_key( $comment, 'comment_content' );
|
1340 |
+
$email = self::get_key( $comment, 'comment_author_email' );
|
1341 |
+
$author = self::get_key( $comment, 'comment_author' );
|
1342 |
+
|
1343 |
+
if ( empty( $body ) ) {
|
1344 |
return array(
|
1345 |
+
'reason' => 'empty',
|
1346 |
);
|
1347 |
}
|
1348 |
|
1349 |
+
if ( empty( $ip ) ) {
|
|
|
1350 |
return array(
|
1351 |
+
'reason' => 'empty',
|
1352 |
);
|
1353 |
}
|
1354 |
|
1355 |
+
if ( get_option( 'require_name_email' ) && ( empty( $email ) || empty( $author ) ) ) {
|
|
|
1356 |
return array(
|
1357 |
+
'reason' => 'empty',
|
1358 |
);
|
1359 |
}
|
1360 |
|
|
|
1361 |
$options = self::get_options();
|
1362 |
|
1363 |
+
if ( $options['already_commented'] && ! empty( $email ) && self::_is_approved_email( $email ) ) {
|
|
|
1364 |
return;
|
1365 |
}
|
1366 |
|
1367 |
+
if ( $options['gravatar_check'] && ! empty( $email ) && 1 === (int) get_option( 'show_avatars', 0 ) && self::_has_valid_gravatar( $email ) ) {
|
1368 |
+
return;
|
|
|
1369 |
}
|
1370 |
|
1371 |
+
// phpcs:disable WordPress.CSRF.NonceVerification.NoNonceVerification
|
1372 |
+
if ( ! empty( $_POST['ab_spam__hidden_field'] ) ) {
|
1373 |
return array(
|
1374 |
+
'reason' => 'css',
|
1375 |
);
|
1376 |
}
|
1377 |
+
// phpcs:enable WordPress.CSRF.NonceVerification.NoNonceVerification
|
1378 |
|
|
|
1379 |
if ( $options['time_check'] && self::_is_shortest_time() ) {
|
1380 |
return array(
|
1381 |
+
'reason' => 'time',
|
1382 |
);
|
1383 |
}
|
1384 |
|
1385 |
+
if ( $options['bbcode_check'] && self::_is_bbcode_spam( $body ) ) {
|
|
|
1386 |
return array(
|
1387 |
+
'reason' => 'bbcode',
|
1388 |
);
|
1389 |
}
|
1390 |
|
1391 |
+
if ( $options['advanced_check'] && self::_is_fake_ip( $ip ) ) {
|
|
|
1392 |
return array(
|
1393 |
+
'reason' => 'server',
|
1394 |
);
|
1395 |
}
|
1396 |
|
|
|
1397 |
if ( $options['regexp_check'] && self::_is_regexp_spam(
|
1398 |
array(
|
1399 |
+
'ip' => $ip,
|
1400 |
'rawurl' => $url,
|
1401 |
+
'host' => self::parse_url( $url, 'host' ),
|
1402 |
+
'body' => $body,
|
1403 |
+
'email' => $email,
|
1404 |
+
'author' => $author,
|
1405 |
)
|
1406 |
) ) {
|
1407 |
return array(
|
1408 |
+
'reason' => 'regexp',
|
1409 |
);
|
1410 |
}
|
1411 |
|
1412 |
+
if ( $options['spam_ip'] && self::_is_db_spam( $ip, $url, $email ) ) {
|
|
|
1413 |
return array(
|
1414 |
+
'reason' => 'localdb',
|
1415 |
);
|
1416 |
}
|
1417 |
|
1418 |
+
if ( $options['country_code'] && self::_is_country_spam( $ip ) ) {
|
|
|
1419 |
return array(
|
1420 |
+
'reason' => 'country',
|
1421 |
);
|
1422 |
}
|
1423 |
|
1424 |
+
if ( $options['translate_api'] && self::_is_lang_spam( $body ) ) {
|
|
|
1425 |
return array(
|
1426 |
+
'reason' => 'lang',
|
1427 |
);
|
1428 |
}
|
1429 |
}
|
1430 |
|
1431 |
|
1432 |
/**
|
1433 |
+
* Check for a Gravatar image
|
1434 |
+
*
|
1435 |
+
* @since 2.6.5
|
1436 |
+
* @change 2.6.5
|
1437 |
+
*
|
1438 |
+
* @param string $email Input email.
|
1439 |
+
* @return boolean Check status (true = Gravatar available).
|
1440 |
+
*/
|
1441 |
+
private static function _has_valid_gravatar( $email ) {
|
1442 |
+
$response = wp_safe_remote_get(
|
1443 |
+
sprintf(
|
1444 |
+
'https://www.gravatar.com/avatar/%s?d=404',
|
1445 |
+
md5( strtolower( trim( $email ) ) )
|
1446 |
+
)
|
1447 |
+
);
|
|
|
1448 |
|
1449 |
+
if ( is_wp_error( $response ) ) {
|
1450 |
+
return null;
|
1451 |
+
}
|
1452 |
|
1453 |
+
if ( wp_remote_retrieve_response_code( $response ) === 200 ) {
|
1454 |
+
return true;
|
1455 |
+
}
|
1456 |
|
1457 |
+
return false;
|
1458 |
+
}
|
1459 |
|
1460 |
|
1461 |
/**
|
1462 |
+
* Check for comment action time
|
1463 |
+
*
|
1464 |
+
* @since 2.6.4
|
1465 |
+
* @change 2.6.4
|
1466 |
+
*
|
1467 |
+
* @return boolean TRUE if the action time is less than 5 seconds
|
1468 |
+
*/
|
1469 |
+
private static function _is_shortest_time() {
|
1470 |
+
// phpcs:disable WordPress.CSRF.NonceVerification.NoNonceVerification
|
1471 |
+
// Everybody can Post.
|
1472 |
+
$init_time = (int) self::get_key( $_POST, 'ab_init_time' );
|
1473 |
+
// phpcs:enable WordPress.CSRF.NonceVerification.NoNonceVerification
|
1474 |
+
if ( 0 === $init_time ) {
|
1475 |
return false;
|
1476 |
}
|
1477 |
|
1478 |
+
if ( time() - $init_time < apply_filters( 'ab_action_time_limit', 5 ) ) {
|
|
|
1479 |
return true;
|
1480 |
}
|
1481 |
|
1482 |
return false;
|
1483 |
}
|
1484 |
|
|
|
1485 |
/**
|
1486 |
+
* Check if the blog name and the title of the blog post from which the trackback originates are equal.
|
1487 |
+
*
|
1488 |
+
* @since 2.6.4
|
1489 |
+
*
|
1490 |
+
* @param string $body The comment body.
|
1491 |
+
* @param string $blog_name The name of the blog.
|
1492 |
+
*
|
1493 |
+
* @return bool
|
1494 |
+
*/
|
1495 |
+
private static function is_trackback_post_title_blog_name_spam( $body, $blog_name ) {
|
1496 |
+
preg_match( '/<strong>(.*)<\/strong>\\n\\n/', $body, $matches );
|
1497 |
+
if ( ! isset( $matches[1] ) ) {
|
1498 |
+
return false;
|
1499 |
+
}
|
1500 |
+
return trim( $matches[1] ) === trim( $blog_name );
|
1501 |
+
}
|
1502 |
|
1503 |
+
|
1504 |
+
/**
|
1505 |
+
* Usage of regexp, also custom
|
1506 |
+
*
|
1507 |
+
* @since 2.5.2
|
1508 |
+
* @change 2.5.6
|
1509 |
+
*
|
1510 |
+
* @param array $comment Array with commentary data.
|
1511 |
+
* @return boolean True for suspicious comment.
|
1512 |
+
*/
|
1513 |
+
private static function _is_regexp_spam( $comment ) {
|
1514 |
$fields = array(
|
1515 |
'ip',
|
1516 |
'host',
|
1519 |
'author',
|
1520 |
);
|
1521 |
|
|
|
1522 |
$patterns = array(
|
1523 |
array(
|
1524 |
+
'host' => '^(www\.)?\d+\w+\.com$',
|
1525 |
+
'body' => '^\w+\s\d+$',
|
1526 |
+
'email' => '@gmail.com$',
|
1527 |
),
|
1528 |
array(
|
1529 |
+
'body' => '\<\!.+?mfunc.+?\>',
|
1530 |
),
|
1531 |
array(
|
1532 |
'author' => 'moncler|north face|vuitton|handbag|burberry|outlet|prada|cialis|viagra|maillot|oakley|ralph lauren|ray ban|iphone|プラダ',
|
1538 |
'body' => 'target[t]?ed (visitors|traffic)|viagra|cialis',
|
1539 |
),
|
1540 |
array(
|
1541 |
+
'body' => 'purchase amazing|buy amazing',
|
1542 |
+
),
|
1543 |
+
array(
|
1544 |
+
'body' => 'dating|sex|lotto|pharmacy',
|
1545 |
+
'email' => '@mail\.ru|@yandex\.',
|
1546 |
),
|
1547 |
);
|
1548 |
|
1549 |
+
$quoted_author = preg_quote( $comment['author'], '/' );
|
1550 |
+
if ( $quoted_author ) {
|
1551 |
$patterns[] = array(
|
1552 |
'body' => sprintf(
|
1553 |
'<a.+?>%s<\/a>$',
|
1561 |
),
|
1562 |
);
|
1563 |
$patterns[] = array(
|
1564 |
+
'email' => '@gmail.com$',
|
1565 |
'author' => '^[a-z0-9-\.]+\.[a-z]{2,6}$',
|
1566 |
+
'host' => sprintf(
|
1567 |
'^%s$',
|
1568 |
$quoted_author
|
1569 |
),
|
1570 |
);
|
1571 |
}
|
1572 |
|
|
|
1573 |
$patterns = apply_filters(
|
1574 |
'antispam_bee_patterns',
|
1575 |
$patterns
|
1576 |
);
|
1577 |
|
|
|
1578 |
if ( ! $patterns ) {
|
1579 |
return false;
|
1580 |
}
|
1581 |
|
1582 |
+
foreach ( $patterns as $pattern ) {
|
|
|
1583 |
$hits = array();
|
1584 |
|
1585 |
+
foreach ( $pattern as $field => $regexp ) {
|
1586 |
+
if ( empty( $field ) || ! in_array( $field, $fields, true ) || empty( $regexp ) ) {
|
|
|
|
|
1587 |
continue;
|
1588 |
}
|
1589 |
|
1590 |
+
$comment[ $field ] = ( function_exists( 'iconv' ) ? iconv( 'utf-8', 'utf-8//TRANSLIT', $comment[ $field ] ) : $comment[ $field ] );
|
|
|
1591 |
|
1592 |
+
if ( empty( $comment[ $field ] ) ) {
|
|
|
1593 |
continue;
|
1594 |
}
|
1595 |
|
1596 |
+
if ( preg_match( '/' . $regexp . '/isu', $comment[ $field ] ) ) {
|
1597 |
+
$hits[ $field ] = true;
|
|
|
1598 |
}
|
1599 |
}
|
1600 |
|
1601 |
+
if ( count( $hits ) === count( $pattern ) ) {
|
1602 |
return true;
|
1603 |
}
|
1604 |
}
|
1608 |
|
1609 |
|
1610 |
/**
|
1611 |
+
* Review a comment on its existence in the local spam
|
1612 |
+
*
|
1613 |
+
* @since 2.0.0
|
1614 |
+
* @change 2.5.4
|
1615 |
+
*
|
1616 |
+
* @param string $ip Comment IP.
|
1617 |
+
* @param string $url Comment URL (optional).
|
1618 |
+
* @param string $email Comment Email (optional).
|
1619 |
+
* @return boolean True for suspicious comment.
|
1620 |
+
*/
|
1621 |
+
private static function _is_db_spam( $ip, $url = '', $email = '' ) {
|
|
|
|
|
|
|
1622 |
global $wpdb;
|
1623 |
|
1624 |
+
// phpcs:disable WordPress.WP.PreparedSQL.NotPrepared
|
1625 |
+
$sql = '
|
1626 |
select
|
1627 |
meta_value as ip
|
1628 |
from
|
1633 |
AND meta.meta_key = "antispam_bee_iphash"
|
1634 |
AND comments.comment_approved="spam"';
|
1635 |
$hashed_ips = $wpdb->get_col( $sql );
|
1636 |
+
if ( ! empty( $hashed_ips ) ) {
|
1637 |
foreach ( $hashed_ips as $hash ) {
|
1638 |
+
if ( wp_check_password( $ip, $hash ) ) {
|
1639 |
return true;
|
1640 |
}
|
1641 |
}
|
1643 |
|
1644 |
$params = array();
|
1645 |
$filter = array();
|
1646 |
+
if ( ! empty( $url ) ) {
|
|
|
1647 |
$filter[] = '`comment_author_url` = %s';
|
1648 |
+
$params[] = wp_unslash( $url );
|
1649 |
}
|
1650 |
|
1651 |
+
if ( ! empty( $email ) ) {
|
|
|
1652 |
$filter[] = '`comment_author_email` = %s';
|
1653 |
+
$params[] = wp_unslash( $email );
|
1654 |
}
|
1655 |
+
if ( empty( $params ) ) {
|
|
|
1656 |
return false;
|
1657 |
}
|
1658 |
|
1659 |
+
// phpcs:disable WordPress.DB.PreparedSQLPlaceholders.ReplacementsWrongNumber
|
1660 |
+
// ToDo: Have a closer look on this SQL Query.
|
1661 |
+
$filter_sql = implode( ' OR ', $filter );
|
1662 |
+
|
1663 |
$result = $wpdb->get_var(
|
1664 |
$wpdb->prepare(
|
1665 |
sprintf(
|
1666 |
"SELECT `comment_ID` FROM `$wpdb->comments` WHERE `comment_approved` = 'spam' AND (%s) LIMIT 1",
|
1667 |
+
$filter_sql
|
1668 |
),
|
1669 |
$params
|
1670 |
)
|
1671 |
);
|
1672 |
+
// phpcs:enable WordPress.DB.PreparedSQLPlaceholders.ReplacementsWrongNumber
|
1673 |
+
// phpcs:enable WordPress.WP.PreparedSQL.NotPrepared
|
1674 |
|
1675 |
+
return ! empty( $result );
|
1676 |
}
|
1677 |
|
1678 |
|
1679 |
/**
|
1680 |
+
* Check for country spam by (anonymized) IP
|
1681 |
+
*
|
1682 |
+
* @since 2.6.9
|
1683 |
+
* @change 2.6.9
|
1684 |
+
*
|
1685 |
+
* @param string $ip IP address.
|
1686 |
+
* @return boolean True if the comment is spam based on country filter.
|
1687 |
+
*/
|
1688 |
+
private static function _is_country_spam( $ip ) {
|
|
|
|
|
|
|
1689 |
$options = self::get_options();
|
1690 |
|
|
|
1691 |
$white = preg_split(
|
1692 |
'/[\s,;]+/',
|
1693 |
$options['country_white'],
|
1701 |
PREG_SPLIT_NO_EMPTY
|
1702 |
);
|
1703 |
|
1704 |
+
if ( empty( $white ) && empty( $black ) ) {
|
|
|
1705 |
return false;
|
1706 |
}
|
1707 |
|
|
|
1708 |
$response = wp_safe_remote_head(
|
1709 |
esc_url_raw(
|
1710 |
sprintf(
|
1711 |
'https://api.ip2country.info/ip?%s',
|
1712 |
+
self::_anonymize_ip( $ip )
|
1713 |
),
|
1714 |
'https'
|
1715 |
)
|
1716 |
);
|
1717 |
|
1718 |
+
if ( is_wp_error( $response ) ) {
|
|
|
1719 |
return false;
|
1720 |
}
|
1721 |
|
1722 |
+
if ( wp_remote_retrieve_response_code( $response ) !== 200 ) {
|
|
|
1723 |
return false;
|
1724 |
}
|
1725 |
|
1726 |
+
$country = (string) wp_remote_retrieve_header( $response, 'x-country-code' );
|
|
|
1727 |
|
1728 |
+
if ( empty( $country ) || strlen( $country ) !== 2 ) {
|
|
|
1729 |
return false;
|
1730 |
}
|
1731 |
|
1732 |
+
if ( ! empty( $black ) ) {
|
1733 |
+
return ( in_array( $country, $black, true ) );
|
|
|
1734 |
}
|
1735 |
|
1736 |
+
return ( ! in_array( $country, $white, true ) );
|
|
|
1737 |
}
|
1738 |
|
1739 |
|
1740 |
/**
|
1741 |
+
* Check for BBCode spam
|
1742 |
+
*
|
1743 |
+
* @since 2.5.1
|
1744 |
+
* @change 2.5.1
|
1745 |
+
*
|
1746 |
+
* @param string $body Content of a comment.
|
1747 |
+
* @return boolean True for BBCode in content
|
1748 |
+
*/
|
1749 |
+
private static function _is_bbcode_spam( $body ) {
|
1750 |
+
return (bool) preg_match( '/\[url[=\]].*\[\/url\]/is', $body );
|
|
|
|
|
1751 |
}
|
1752 |
|
1753 |
|
1754 |
/**
|
1755 |
+
* Check for an already approved e-mail address
|
1756 |
+
*
|
1757 |
+
* @since 2.0
|
1758 |
+
* @change 2.5.1
|
1759 |
+
*
|
1760 |
+
* @param string $email E-mail address.
|
1761 |
+
* @return boolean True for a found entry.
|
1762 |
+
*/
|
1763 |
+
private static function _is_approved_email( $email ) {
|
|
|
|
|
|
|
1764 |
global $wpdb;
|
1765 |
|
|
|
1766 |
$result = $wpdb->get_var(
|
1767 |
$wpdb->prepare(
|
1768 |
"SELECT `comment_ID` FROM `$wpdb->comments` WHERE `comment_approved` = '1' AND `comment_author_email` = %s LIMIT 1",
|
1769 |
+
wp_unslash( $email )
|
1770 |
)
|
1771 |
);
|
1772 |
|
|
|
1773 |
if ( $result ) {
|
1774 |
return true;
|
1775 |
}
|
1779 |
|
1780 |
|
1781 |
/**
|
1782 |
+
* Check for a fake IP
|
1783 |
+
*
|
1784 |
+
* @since 2.0
|
1785 |
+
* @change 2.6.2
|
1786 |
+
*
|
1787 |
+
* @param string $client_ip Client IP.
|
1788 |
+
* @param string $client_host Client Host (optional).
|
1789 |
+
* @return boolean True if fake IP.
|
1790 |
+
*/
|
1791 |
+
private static function _is_fake_ip( $client_ip, $client_host = '' ) {
|
1792 |
+
$host_by_ip = gethostbyaddr( $client_ip );
|
|
|
|
|
|
|
1793 |
|
1794 |
+
if ( self::_is_ipv6( $client_ip ) ) {
|
1795 |
+
return $client_ip !== $host_by_ip;
|
|
|
1796 |
}
|
1797 |
|
1798 |
+
if ( empty( $client_host ) ) {
|
1799 |
+
$ip_by_host = gethostbyname( $host_by_ip );
|
|
|
1800 |
|
1801 |
if ( $ip_by_host === $host_by_ip ) {
|
1802 |
return false;
|
1803 |
}
|
|
|
|
|
1804 |
} else {
|
1805 |
if ( $host_by_ip === $client_ip ) {
|
1806 |
return true;
|
1807 |
}
|
1808 |
|
1809 |
+
$ip_by_host = gethostbyname( $client_host );
|
1810 |
}
|
1811 |
|
1812 |
+
if ( strpos( $client_ip, self::_cut_ip( $ip_by_host ) ) === false ) {
|
1813 |
return true;
|
1814 |
}
|
1815 |
|
1821 |
*
|
1822 |
* @since 2.0
|
1823 |
* @change 2.6.6
|
1824 |
+
* @change 2.8.2
|
1825 |
*
|
1826 |
* @param string $comment_content Content of the comment.
|
1827 |
*
|
1828 |
+
* @return boolean TRUE if it is spam.
|
1829 |
*/
|
|
|
1830 |
private static function _is_lang_spam( $comment_content ) {
|
|
|
1831 |
$allowed_lang = (array) self::get_option( 'translate_lang' );
|
1832 |
|
|
|
1833 |
$comment_text = wp_strip_all_tags( $comment_content );
|
1834 |
|
1835 |
+
if ( empty( $allowed_lang ) || empty( $comment_text ) ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1836 |
return false;
|
1837 |
}
|
1838 |
|
1839 |
/**
|
1840 |
+
* Filters the detected language. With this filter, other detection methods can skip in and detect the language.
|
1841 |
*
|
1842 |
+
* @since 2.8.2
|
1843 |
*
|
1844 |
+
* @param null $detected_lang The detected language.
|
1845 |
+
* @param string $comment_text The text, to detect the language.
|
1846 |
*
|
1847 |
+
* @return null|string The detected language or null.
|
1848 |
*/
|
1849 |
+
$detected_lang = apply_filters( 'antispam_bee_detected_lang', null, $comment_text );
|
1850 |
+
if ( null !== $detected_lang ) {
|
1851 |
+
return ! in_array( $detected_lang, $allowed_lang, true );
|
1852 |
+
}
|
|
|
|
|
1853 |
|
1854 |
+
if ( mb_strlen( $comment_text ) < 10 ) {
|
1855 |
+
return false;
|
1856 |
+
}
|
1857 |
+
|
1858 |
+
$response = wp_safe_remote_post(
|
1859 |
+
'https://api.pluginkollektiv.org/language/v1/',
|
1860 |
+
array( 'body' => wp_json_encode( array( 'body' => $comment_text ) ) )
|
|
|
|
|
1861 |
);
|
1862 |
|
|
|
1863 |
if ( is_wp_error( $response )
|
1864 |
+
|| wp_remote_retrieve_response_code( $response ) !== 200 ) {
|
1865 |
return false;
|
1866 |
}
|
1867 |
|
1868 |
+
$detected_lang = wp_remote_retrieve_body( $response );
|
1869 |
+
if ( ! $detected_lang ) {
|
1870 |
return false;
|
1871 |
}
|
1872 |
|
1873 |
+
$detected_lang = json_decode( $detected_lang );
|
1874 |
+
if ( ! $detected_lang || ! isset( $detected_lang->code ) ) {
|
1875 |
return false;
|
1876 |
}
|
1877 |
|
1878 |
+
return ! in_array( self::_map_lang_code( $detected_lang->code ), $allowed_lang, true );
|
1879 |
+
}
|
1880 |
+
|
1881 |
+
/**
|
1882 |
+
* Map franc language codes
|
1883 |
+
*
|
1884 |
+
* @since 2.9.0
|
1885 |
+
*
|
1886 |
+
* @param string $franc_code The franc code, received from the service.
|
1887 |
+
*
|
1888 |
+
* @return string Mapped ISO code
|
1889 |
+
*/
|
1890 |
+
private static function _map_lang_code( $franc_code ) {
|
1891 |
+
$codes = array(
|
1892 |
+
'zha' => 'za',
|
1893 |
+
'zho' => 'zh',
|
1894 |
+
'zul' => 'zu',
|
1895 |
+
'yid' => 'yi',
|
1896 |
+
'yor' => 'yo',
|
1897 |
+
'xho' => 'xh',
|
1898 |
+
'wln' => 'wa',
|
1899 |
+
'wol' => 'wo',
|
1900 |
+
'ven' => 've',
|
1901 |
+
'vie' => 'vi',
|
1902 |
+
'vol' => 'vo',
|
1903 |
+
'uig' => 'ug',
|
1904 |
+
'ukr' => 'uk',
|
1905 |
+
'urd' => 'ur',
|
1906 |
+
'uzb' => 'uz',
|
1907 |
+
'tah' => 'ty',
|
1908 |
+
'tam' => 'ta',
|
1909 |
+
'tat' => 'tt',
|
1910 |
+
'tel' => 'te',
|
1911 |
+
'tgk' => 'tg',
|
1912 |
+
'tgl' => 'tl',
|
1913 |
+
'tha' => 'th',
|
1914 |
+
'tir' => 'ti',
|
1915 |
+
'ton' => 'to',
|
1916 |
+
'tsn' => 'tn',
|
1917 |
+
'tso' => 'ts',
|
1918 |
+
'tuk' => 'tk',
|
1919 |
+
'tur' => 'tr',
|
1920 |
+
'twi' => 'tw',
|
1921 |
+
'sag' => 'sg',
|
1922 |
+
'san' => 'sa',
|
1923 |
+
'sin' => 'si',
|
1924 |
+
'slk' => 'sk',
|
1925 |
+
'slv' => 'sl',
|
1926 |
+
'sme' => 'se',
|
1927 |
+
'smo' => 'sm',
|
1928 |
+
'sna' => 'sn',
|
1929 |
+
'snd' => 'sd',
|
1930 |
+
'som' => 'so',
|
1931 |
+
'sot' => 'st',
|
1932 |
+
'spa' => 'es',
|
1933 |
+
'sqi' => 'sq',
|
1934 |
+
'srd' => 'sc',
|
1935 |
+
'srp' => 'sr',
|
1936 |
+
'ssw' => 'ss',
|
1937 |
+
'sun' => 'su',
|
1938 |
+
'swa' => 'sw',
|
1939 |
+
'swe' => 'sv',
|
1940 |
+
'roh' => 'rm',
|
1941 |
+
'ron' => 'ro',
|
1942 |
+
'run' => 'rn',
|
1943 |
+
'rus' => 'ru',
|
1944 |
+
'que' => 'qu',
|
1945 |
+
'pan' => 'pa',
|
1946 |
+
'pli' => 'pi',
|
1947 |
+
'pol' => 'pl',
|
1948 |
+
'por' => 'pt',
|
1949 |
+
'pus' => 'ps',
|
1950 |
+
'oci' => 'oc',
|
1951 |
+
'oji' => 'oj',
|
1952 |
+
'ori' => 'or',
|
1953 |
+
'orm' => 'om',
|
1954 |
+
'oss' => 'os',
|
1955 |
+
'nau' => 'na',
|
1956 |
+
'nav' => 'nv',
|
1957 |
+
'nbl' => 'nr',
|
1958 |
+
'nde' => 'nd',
|
1959 |
+
'ndo' => 'ng',
|
1960 |
+
'nep' => 'ne',
|
1961 |
+
'nld' => 'nl',
|
1962 |
+
'nno' => 'nn',
|
1963 |
+
'nob' => 'nb',
|
1964 |
+
'nor' => 'no',
|
1965 |
+
'nya' => 'ny',
|
1966 |
+
'mah' => 'mh',
|
1967 |
+
'mal' => 'ml',
|
1968 |
+
'mar' => 'mr',
|
1969 |
+
'mkd' => 'mk',
|
1970 |
+
'mlg' => 'mg',
|
1971 |
+
'mlt' => 'mt',
|
1972 |
+
'mon' => 'mn',
|
1973 |
+
'mri' => 'mi',
|
1974 |
+
'msa' => 'ms',
|
1975 |
+
'mya' => 'my',
|
1976 |
+
'lao' => 'lo',
|
1977 |
+
'lat' => 'la',
|
1978 |
+
'lav' => 'lv',
|
1979 |
+
'lim' => 'li',
|
1980 |
+
'lin' => 'ln',
|
1981 |
+
'lit' => 'lt',
|
1982 |
+
'ltz' => 'lb',
|
1983 |
+
'lub' => 'lu',
|
1984 |
+
'lug' => 'lg',
|
1985 |
+
'kal' => 'kl',
|
1986 |
+
'kan' => 'kn',
|
1987 |
+
'kas' => 'ks',
|
1988 |
+
'kat' => 'ka',
|
1989 |
+
'kau' => 'kr',
|
1990 |
+
'kaz' => 'kk',
|
1991 |
+
'khm' => 'km',
|
1992 |
+
'kik' => 'ki',
|
1993 |
+
'kin' => 'rw',
|
1994 |
+
'kir' => 'ky',
|
1995 |
+
'kom' => 'kv',
|
1996 |
+
'kon' => 'kg',
|
1997 |
+
'kor' => 'ko',
|
1998 |
+
'kua' => 'kj',
|
1999 |
+
'kur' => 'ku',
|
2000 |
+
'jav' => 'jv',
|
2001 |
+
'jpn' => 'ja',
|
2002 |
+
'ibo' => 'ig',
|
2003 |
+
'ido' => 'io',
|
2004 |
+
'iii' => 'ii',
|
2005 |
+
'iku' => 'iu',
|
2006 |
+
'ile' => 'ie',
|
2007 |
+
'ina' => 'ia',
|
2008 |
+
'ind' => 'id',
|
2009 |
+
'ipk' => 'ik',
|
2010 |
+
'isl' => 'is',
|
2011 |
+
'ita' => 'it',
|
2012 |
+
'hat' => 'ht',
|
2013 |
+
'hau' => 'ha',
|
2014 |
+
'hbs' => 'sh',
|
2015 |
+
'heb' => 'he',
|
2016 |
+
'her' => 'hz',
|
2017 |
+
'hin' => 'hi',
|
2018 |
+
'hmo' => 'ho',
|
2019 |
+
'hrv' => 'hr',
|
2020 |
+
'hun' => 'hu',
|
2021 |
+
'hye' => 'hy',
|
2022 |
+
'gla' => 'gd',
|
2023 |
+
'gle' => 'ga',
|
2024 |
+
'glg' => 'gl',
|
2025 |
+
'glv' => 'gv',
|
2026 |
+
'grn' => 'gn',
|
2027 |
+
'guj' => 'gu',
|
2028 |
+
'fao' => 'fo',
|
2029 |
+
'fas' => 'fa',
|
2030 |
+
'fij' => 'fj',
|
2031 |
+
'fin' => 'fi',
|
2032 |
+
'fra' => 'fr',
|
2033 |
+
'fry' => 'fy',
|
2034 |
+
'ful' => 'ff',
|
2035 |
+
'ell' => 'el',
|
2036 |
+
'eng' => 'en',
|
2037 |
+
'epo' => 'eo',
|
2038 |
+
'est' => 'et',
|
2039 |
+
'eus' => 'eu',
|
2040 |
+
'ewe' => 'ee',
|
2041 |
+
'dan' => 'da',
|
2042 |
+
'deu' => 'de',
|
2043 |
+
'div' => 'dv',
|
2044 |
+
'dzo' => 'dz',
|
2045 |
+
'cat' => 'ca',
|
2046 |
+
'ces' => 'cs',
|
2047 |
+
'cha' => 'ch',
|
2048 |
+
'che' => 'ce',
|
2049 |
+
'chu' => 'cu',
|
2050 |
+
'chv' => 'cv',
|
2051 |
+
'cor' => 'kw',
|
2052 |
+
'cos' => 'co',
|
2053 |
+
'cre' => 'cr',
|
2054 |
+
'cym' => 'cy',
|
2055 |
+
'bak' => 'ba',
|
2056 |
+
'bam' => 'bm',
|
2057 |
+
'bel' => 'be',
|
2058 |
+
'ben' => 'bn',
|
2059 |
+
'bis' => 'bi',
|
2060 |
+
'bod' => 'bo',
|
2061 |
+
'bos' => 'bs',
|
2062 |
+
'bre' => 'br',
|
2063 |
+
'bul' => 'bg',
|
2064 |
+
'aar' => 'aa',
|
2065 |
+
'abk' => 'ab',
|
2066 |
+
'afr' => 'af',
|
2067 |
+
'aka' => 'ak',
|
2068 |
+
'amh' => 'am',
|
2069 |
+
'ara' => 'ar',
|
2070 |
+
'arg' => 'an',
|
2071 |
+
'asm' => 'as',
|
2072 |
+
'ava' => 'av',
|
2073 |
+
'ave' => 'ae',
|
2074 |
+
'aym' => 'ay',
|
2075 |
+
'aze' => 'az',
|
2076 |
+
);
|
2077 |
+
|
2078 |
+
if ( array_key_exists( $franc_code, $codes ) ) {
|
2079 |
+
return $codes[ $franc_code ];
|
2080 |
}
|
2081 |
|
2082 |
+
return $franc_code;
|
2083 |
}
|
2084 |
|
2085 |
/**
|
2086 |
+
* Trim IP addresses
|
2087 |
+
*
|
2088 |
+
* @since 0.1
|
2089 |
+
* @change 2.5.1
|
2090 |
+
*
|
2091 |
+
* @param string $ip Original IP.
|
2092 |
+
* @param boolean $cut_end Shortening the end.
|
2093 |
+
* @return string Shortened IP.
|
2094 |
+
*/
|
2095 |
+
private static function _cut_ip( $ip, $cut_end = true ) {
|
2096 |
+
$separator = ( self::_is_ipv4( $ip ) ? '.' : ':' );
|
|
|
|
|
2097 |
|
2098 |
return str_replace(
|
2099 |
+
( $cut_end ? strrchr( $ip, $separator ) : strstr( $ip, $separator ) ),
|
2100 |
'',
|
2101 |
$ip
|
2102 |
);
|
2104 |
|
2105 |
|
2106 |
/**
|
2107 |
+
* Anonymize the IP addresses
|
2108 |
+
*
|
2109 |
+
* @since 2.5.1
|
2110 |
+
* @change 2.5.1
|
2111 |
+
*
|
2112 |
+
* @param string $ip Original IP.
|
2113 |
+
* @return string Anonymous IP.
|
2114 |
+
*/
|
2115 |
+
private static function _anonymize_ip( $ip ) {
|
2116 |
+
if ( self::_is_ipv4( $ip ) ) {
|
2117 |
+
return self::_cut_ip( $ip ) . '.0';
|
|
|
|
|
2118 |
}
|
2119 |
|
2120 |
+
return self::_cut_ip( $ip, false ) . ':0:0:0:0:0:0:0';
|
2121 |
}
|
2122 |
|
2123 |
|
2124 |
/**
|
2125 |
+
* Rotates the IP address
|
2126 |
+
*
|
2127 |
+
* @since 2.4.5
|
2128 |
+
* @change 2.4.5
|
2129 |
+
*
|
2130 |
+
* @param string $ip IP address.
|
2131 |
+
* @return string Turned IP address.
|
2132 |
+
*/
|
2133 |
+
private static function _reverse_ip( $ip ) {
|
|
|
|
|
2134 |
return implode(
|
2135 |
'.',
|
2136 |
array_reverse(
|
2144 |
|
2145 |
|
2146 |
/**
|
2147 |
+
* Check for an IPv4 address
|
2148 |
+
*
|
2149 |
+
* @since 2.4
|
2150 |
+
* @change 2.6.4
|
2151 |
+
*
|
2152 |
+
* @param string $ip IP to validate.
|
2153 |
+
* @return integer TRUE if IPv4.
|
2154 |
+
*/
|
2155 |
+
private static function _is_ipv4( $ip ) {
|
2156 |
+
if ( function_exists( 'filter_var' ) ) {
|
|
|
|
|
2157 |
return filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) !== false;
|
2158 |
} else {
|
2159 |
+
return preg_match( '/^\d{1,3}(\.\d{1,3}){3,3}$/', $ip );
|
2160 |
}
|
2161 |
}
|
2162 |
|
2163 |
|
2164 |
/**
|
2165 |
+
* Check for an IPv6 address
|
2166 |
+
*
|
2167 |
+
* @since 2.6.2
|
2168 |
+
* @change 2.6.4
|
2169 |
+
*
|
2170 |
+
* @param string $ip IP to validate.
|
2171 |
+
* @return boolean TRUE if IPv6.
|
2172 |
+
*/
|
2173 |
+
private static function _is_ipv6( $ip ) {
|
2174 |
+
if ( function_exists( 'filter_var' ) ) {
|
|
|
|
|
2175 |
return filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) !== false;
|
2176 |
} else {
|
2177 |
+
return ! self::_is_ipv4( $ip );
|
2178 |
}
|
2179 |
}
|
2180 |
|
2181 |
|
2182 |
/**
|
2183 |
+
* Testing on mobile devices
|
2184 |
+
*
|
2185 |
+
* @since 0.1
|
2186 |
+
* @change 2.4
|
2187 |
+
*
|
2188 |
+
* @return boolean TRUE if "wptouch" is active
|
2189 |
+
*/
|
2190 |
+
private static function _is_mobile() {
|
2191 |
+
return strpos( get_template_directory(), 'wptouch' );
|
|
|
|
|
2192 |
}
|
2193 |
|
2194 |
|
2195 |
|
2196 |
+
/*
|
2197 |
+
* ############################
|
2198 |
+
* ##### SPAM-TREATMENT #####
|
2199 |
+
* ############################
|
2200 |
+
*/
|
2201 |
|
2202 |
/**
|
2203 |
+
* Execution of the delete/marking process
|
2204 |
+
*
|
2205 |
+
* @since 0.1
|
2206 |
+
* @change 2.6.0
|
2207 |
+
*
|
2208 |
+
* @param array $comment Untreated commentary data.
|
2209 |
+
* @param string $reason Reason for suspicion.
|
2210 |
+
* @param boolean $is_ping Ping (optional).
|
2211 |
+
* @return array $comment Treated commentary data.
|
2212 |
+
*/
|
2213 |
+
private static function _handle_spam_request( $comment, $reason, $is_ping = false ) {
|
2214 |
|
|
|
|
|
|
|
2215 |
$options = self::get_options();
|
2216 |
|
2217 |
+
$spam_remove = ! $options['flag_spam'];
|
2218 |
+
$spam_notice = ! $options['no_notice'];
|
|
|
2219 |
|
2220 |
+
// Filter settings.
|
2221 |
$ignore_filter = $options['ignore_filter'];
|
2222 |
+
$ignore_type = $options['ignore_type'];
|
2223 |
+
$ignore_reason = in_array( $reason, (array) $options['ignore_reasons'], true );
|
2224 |
|
2225 |
+
// Remember spam.
|
2226 |
+
self::_update_spam_log( $comment );
|
2227 |
self::_update_spam_count();
|
2228 |
self::_update_daily_stats();
|
2229 |
|
2230 |
+
// Delete spam.
|
2231 |
if ( $spam_remove ) {
|
2232 |
self::_go_in_peace();
|
2233 |
}
|
2234 |
|
2235 |
+
if ( $ignore_filter && ( ( 1 === (int) $ignore_type && $is_ping ) || ( 2 === (int) $ignore_type && ! $is_ping ) ) ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2236 |
self::_go_in_peace();
|
2237 |
}
|
2238 |
|
2239 |
+
// Spam reason.
|
2240 |
if ( $ignore_reason ) {
|
2241 |
self::_go_in_peace();
|
2242 |
}
|
2243 |
self::$_reason = $reason;
|
2244 |
|
2245 |
+
// Mark spam.
|
2246 |
add_filter(
|
2247 |
'pre_comment_approved',
|
2248 |
array(
|
2249 |
__CLASS__,
|
2250 |
+
'return_spam',
|
2251 |
)
|
2252 |
);
|
2253 |
|
2254 |
+
// Send e-mail.
|
2255 |
add_action(
|
2256 |
'comment_post',
|
2257 |
array(
|
2258 |
__CLASS__,
|
2259 |
+
'send_mail_notification',
|
2260 |
)
|
2261 |
);
|
2262 |
|
2263 |
+
// Spam reason as comment meta.
|
2264 |
if ( $spam_notice ) {
|
2265 |
add_action(
|
2266 |
'comment_post',
|
2267 |
array(
|
2268 |
__CLASS__,
|
2269 |
+
'add_spam_reason_to_comment',
|
2270 |
)
|
2271 |
);
|
2272 |
}
|
2276 |
|
2277 |
|
2278 |
/**
|
2279 |
+
* Logfile with detected spam
|
2280 |
+
*
|
2281 |
+
* @since 2.5.7
|
2282 |
+
* @change 2.6.1
|
2283 |
+
*
|
2284 |
+
* @param array $comment Array with commentary data.
|
2285 |
+
* @return mixed FALSE in case of error
|
2286 |
+
*/
|
2287 |
+
private static function _update_spam_log( $comment ) {
|
2288 |
+
if ( ! defined( 'ANTISPAM_BEE_LOG_FILE' ) || ! ANTISPAM_BEE_LOG_FILE || ! is_writable( ANTISPAM_BEE_LOG_FILE ) || validate_file( ANTISPAM_BEE_LOG_FILE ) === 1 ) {
|
|
|
|
|
|
|
2289 |
return false;
|
2290 |
}
|
2291 |
|
|
|
2292 |
$entry = sprintf(
|
2293 |
'%s comment for post=%d from host=%s marked as spam%s',
|
2294 |
+
current_time( 'mysql' ),
|
2295 |
$comment['comment_post_ID'],
|
2296 |
$comment['comment_author_IP'],
|
2297 |
PHP_EOL
|
2298 |
);
|
2299 |
|
|
|
2300 |
file_put_contents(
|
2301 |
ANTISPAM_BEE_LOG_FILE,
|
2302 |
$entry,
|
2306 |
|
2307 |
|
2308 |
/**
|
2309 |
+
* Sends the 403 header and terminates the connection
|
2310 |
+
*
|
2311 |
+
* @since 2.5.6
|
2312 |
+
* @change 2.5.6
|
2313 |
+
*/
|
2314 |
+
private static function _go_in_peace() {
|
2315 |
+
status_header( 403 );
|
2316 |
+
die( 'Spam deleted.' );
|
|
|
|
|
2317 |
}
|
2318 |
|
2319 |
|
2320 |
/**
|
2321 |
+
* Return real client IP
|
2322 |
+
*
|
2323 |
+
* @since 2.6.1
|
2324 |
+
* @change 2.6.1
|
2325 |
+
*
|
2326 |
+
* @return mixed $ip Client IP
|
2327 |
+
*/
|
2328 |
+
public static function get_client_ip() {
|
2329 |
+
// phpcs:disable WordPress.VIP.ValidatedSanitizedInput.InputNotSanitized
|
2330 |
+
// Sanitization of $ip takes place further down.
|
2331 |
+
if ( isset( $_SERVER['HTTP_CLIENT_IP'] ) ) {
|
2332 |
+
$ip = wp_unslash( $_SERVER['HTTP_CLIENT_IP'] );
|
2333 |
+
} elseif ( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
|
2334 |
+
$ip = wp_unslash( $_SERVER['HTTP_X_FORWARDED_FOR'] );
|
2335 |
+
} elseif ( isset( $_SERVER['HTTP_X_FORWARDED'] ) ) {
|
2336 |
+
$ip = wp_unslash( $_SERVER['HTTP_X_FORWARDED'] );
|
2337 |
+
} elseif ( isset( $_SERVER['HTTP_FORWARDED_FOR'] ) ) {
|
2338 |
+
$ip = wp_unslash( $_SERVER['HTTP_FORWARDED_FOR'] );
|
2339 |
+
} elseif ( isset( $_SERVER['HTTP_FORWARDED'] ) ) {
|
2340 |
+
$ip = wp_unslash( $_SERVER['HTTP_FORWARDED'] );
|
2341 |
+
} elseif ( isset( $_SERVER['REMOTE_ADDR'] ) ) {
|
2342 |
+
$ip = wp_unslash( $_SERVER['REMOTE_ADDR'] );
|
2343 |
} else {
|
2344 |
return '';
|
2345 |
}
|
2346 |
+
// phpcs:enable WordPress.VIP.ValidatedSanitizedInput.InputNotSanitized
|
2347 |
|
2348 |
+
if ( strpos( $ip, ',' ) !== false ) {
|
2349 |
+
$ips = explode( ',', $ip );
|
2350 |
+
$ip = trim( $ips[0] );
|
2351 |
}
|
2352 |
|
2353 |
+
if ( function_exists( 'filter_var' ) ) {
|
2354 |
return filter_var(
|
2355 |
$ip,
|
2356 |
FILTER_VALIDATE_IP
|
2364 |
);
|
2365 |
}
|
2366 |
|
|
|
2367 |
/**
|
2368 |
+
* Add spam reason as comment data
|
2369 |
+
*
|
2370 |
+
* @since 2.6.0
|
2371 |
+
* @change 2.6.0
|
2372 |
+
*
|
2373 |
+
* @param integer $comment_id Comment ID.
|
2374 |
+
*/
|
2375 |
+
public static function add_spam_reason_to_comment( $comment_id ) {
|
|
|
|
|
2376 |
add_comment_meta(
|
2377 |
$comment_id,
|
2378 |
'antispam_bee_reason',
|
2380 |
);
|
2381 |
}
|
2382 |
|
2383 |
+
/**
|
2384 |
+
* Saves the IP address.
|
2385 |
+
*
|
2386 |
+
* @param int $comment_id The ID of the comment.
|
2387 |
+
*/
|
2388 |
+
public static function save_ip_hash( $comment_id ) {
|
2389 |
+
$hashed_ip = self::hash_ip( self::get_client_ip() );
|
2390 |
add_comment_meta(
|
2391 |
$comment_id,
|
2392 |
'antispam_bee_iphash',
|
2394 |
);
|
2395 |
}
|
2396 |
|
2397 |
+
/**
|
2398 |
+
* Hashes an IP address
|
2399 |
+
*
|
2400 |
+
* @param string $ip The IP address to hash.
|
2401 |
+
*
|
2402 |
+
* @return string
|
2403 |
+
*/
|
2404 |
+
public static function hash_ip( $ip ) {
|
2405 |
return wp_hash_password( $ip );
|
2406 |
}
|
2407 |
|
2408 |
|
2409 |
/**
|
2410 |
+
* Delete spam reason as comment data
|
2411 |
+
*
|
2412 |
+
* @since 2.6.0
|
2413 |
+
* @change 2.6.0
|
2414 |
+
*
|
2415 |
+
* @param integer $comment_id Comment ID.
|
2416 |
+
*/
|
2417 |
+
public static function delete_spam_reason_by_comment( $comment_id ) {
|
|
|
|
|
2418 |
delete_comment_meta(
|
2419 |
$comment_id,
|
2420 |
'antispam_bee_reason'
|
2425 |
* Get the current post ID.
|
2426 |
*
|
2427 |
* @since 2.7.1
|
|
|
|
|
2428 |
*/
|
2429 |
public static function populate_post_id() {
|
2430 |
|
2435 |
|
2436 |
|
2437 |
/**
|
2438 |
+
* Send notification via e-mail
|
2439 |
+
*
|
2440 |
+
* @since 0.1
|
2441 |
+
* @change 2.5.7
|
2442 |
+
*
|
2443 |
+
* @hook string antispam_bee_notification_subject Custom subject for notification mails
|
2444 |
+
*
|
2445 |
+
* @param int $id ID of the comment.
|
2446 |
+
* @return int $id ID of the comment.
|
2447 |
+
*/
|
2448 |
+
public static function send_mail_notification( $id ) {
|
|
|
|
|
|
|
2449 |
$options = self::get_options();
|
2450 |
|
2451 |
+
if ( ! $options['email_notify'] ) {
|
|
|
2452 |
return $id;
|
2453 |
}
|
2454 |
|
2455 |
+
$comment = get_comment( $id, ARRAY_A );
|
|
|
2456 |
|
2457 |
+
if ( empty( $comment ) ) {
|
|
|
2458 |
return $id;
|
2459 |
}
|
2460 |
|
2461 |
+
$post = get_post( $comment['comment_post_ID'] );
|
2462 |
+
if ( ! $post ) {
|
2463 |
return $id;
|
2464 |
}
|
2465 |
|
|
|
2466 |
self::load_plugin_lang();
|
2467 |
|
|
|
2468 |
$subject = sprintf(
|
2469 |
'[%s] %s',
|
2470 |
stripslashes_deep(
|
2471 |
html_entity_decode(
|
2472 |
+
get_bloginfo( 'name' ),
|
2473 |
ENT_QUOTES
|
2474 |
)
|
2475 |
),
|
2476 |
+
esc_html__( 'Comment marked as spam', 'antispam-bee' )
|
2477 |
);
|
2478 |
|
2479 |
+
// Content.
|
2480 |
+
$content = strip_tags( stripslashes( $comment['comment_content'] ) );
|
2481 |
+
if ( ! $content ) {
|
2482 |
$content = sprintf(
|
2483 |
'-- %s --',
|
2484 |
+
esc_html__( 'Content removed by Antispam Bee', 'antispam-bee' )
|
2485 |
);
|
2486 |
}
|
2487 |
|
2488 |
+
// Body.
|
2489 |
$body = sprintf(
|
2490 |
"%s \"%s\"\r\n\r\n",
|
2491 |
+
esc_html__( 'New spam comment on your post', 'antispam-bee' ),
|
2492 |
+
strip_tags( $post->post_title )
|
2493 |
+
) . sprintf(
|
2494 |
"%s: %s\r\n",
|
2495 |
+
esc_html__( 'Author', 'antispam-bee' ),
|
2496 |
+
( empty( $comment['comment_author'] ) ? '' : strip_tags( $comment['comment_author'] ) )
|
2497 |
+
) . sprintf(
|
2498 |
"URL: %s\r\n",
|
2499 |
+
// empty check exists.
|
2500 |
+
esc_url( $comment['comment_author_url'] )
|
2501 |
+
) . sprintf(
|
2502 |
"%s: %s\r\n",
|
2503 |
+
esc_html__( 'Type', 'antispam-bee' ),
|
2504 |
+
esc_html( ( empty( $comment['comment_type'] ) ? __( 'Comment', 'antispam-bee' ) : __( 'Trackback', 'antispam-bee' ) ) )
|
2505 |
+
) . sprintf(
|
2506 |
"Whois: http://whois.arin.net/rest/ip/%s\r\n",
|
2507 |
$comment['comment_author_IP']
|
2508 |
+
) . sprintf(
|
2509 |
"%s: %s\r\n\r\n",
|
2510 |
+
esc_html__( 'Spam Reason', 'antispam-bee' ),
|
2511 |
+
esc_html( self::$defaults['reasons'][ self::$_reason ] )
|
2512 |
+
) . sprintf(
|
2513 |
"%s\r\n\r\n\r\n",
|
2514 |
$content
|
2515 |
+
) . (
|
2516 |
EMPTY_TRASH_DAYS ? (
|
2517 |
sprintf(
|
2518 |
"%s: %s\r\n",
|
2519 |
+
esc_html__( 'Trash it', 'antispam-bee' ),
|
2520 |
+
admin_url( 'comment.php?action=trash&c=' . $id )
|
2521 |
)
|
2522 |
) : (
|
2523 |
sprintf(
|
2524 |
"%s: %s\r\n",
|
2525 |
+
esc_html__( 'Delete it', 'antispam-bee' ),
|
2526 |
+
admin_url( 'comment.php?action=delete&c=' . $id )
|
2527 |
)
|
2528 |
)
|
2529 |
+
) . sprintf(
|
2530 |
+
"%s: %s\r\n",
|
2531 |
+
esc_html__( 'Approve it', 'antispam-bee' ),
|
2532 |
+
admin_url( 'comment.php?action=approve&c=' . $id )
|
2533 |
+
) . sprintf(
|
2534 |
"%s: %s\r\n\r\n",
|
2535 |
+
esc_html__( 'Spam list', 'antispam-bee' ),
|
2536 |
+
admin_url( 'edit-comments.php?comment_status=spam' )
|
2537 |
+
) . sprintf(
|
2538 |
"%s\r\n%s\r\n",
|
2539 |
+
esc_html__( 'Notify message by Antispam Bee', 'antispam-bee' ),
|
2540 |
+
esc_html__( 'http://antispambee.com', 'antispam-bee' )
|
2541 |
);
|
2542 |
|
|
|
2543 |
wp_mail(
|
2544 |
/**
|
2545 |
+
* Filters the recipients of the spam notification.
|
2546 |
+
*
|
2547 |
* @param array The recipients array.
|
2548 |
+
*/
|
2549 |
apply_filters(
|
2550 |
'antispam_bee_notification_recipients',
|
2551 |
+
array( get_bloginfo( 'admin_email' ) )
|
2552 |
),
|
2553 |
/**
|
2554 |
+
* Filters the subject of the spam notification.
|
2555 |
+
*
|
2556 |
* @param string $subject subject line.
|
2557 |
+
*/
|
2558 |
apply_filters(
|
2559 |
'antispam_bee_notification_subject',
|
2560 |
$subject
|
2567 |
|
2568 |
|
2569 |
|
2570 |
+
/*
|
2571 |
+
* ############################
|
2572 |
+
* ####### STATISTICS #######
|
2573 |
+
* ############################
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2574 |
*/
|
2575 |
|
2576 |
+
/**
|
2577 |
+
* Return the number of spam comments
|
2578 |
+
*
|
2579 |
+
* @since 0.1
|
2580 |
+
* @change 2.4
|
2581 |
+
*/
|
2582 |
+
private static function _get_spam_count() {
|
2583 |
+
// Init.
|
2584 |
+
$count = self::get_option( 'spam_count' );
|
2585 |
|
2586 |
+
// Fire.
|
2587 |
+
return ( get_locale() === 'de_DE' ? number_format( $count, 0, '', '.' ) : number_format_i18n( $count ) );
|
2588 |
}
|
2589 |
|
2590 |
|
2591 |
/**
|
2592 |
+
* Output the number of spam comments
|
2593 |
+
*
|
2594 |
+
* @since 0.1
|
2595 |
+
* @change 2.4
|
2596 |
+
*/
|
2597 |
+
public static function the_spam_count() {
|
|
|
|
|
2598 |
echo esc_html( self::_get_spam_count() );
|
2599 |
}
|
2600 |
|
2601 |
|
2602 |
/**
|
2603 |
+
* Update the number of spam comments
|
2604 |
+
*
|
2605 |
+
* @since 0.1
|
2606 |
+
* @change 2.6.1
|
2607 |
+
*/
|
2608 |
+
private static function _update_spam_count() {
|
2609 |
+
// Skip if not enabled.
|
2610 |
+
if ( ! self::get_option( 'dashboard_count' ) ) {
|
|
|
|
|
2611 |
return;
|
2612 |
}
|
2613 |
|
2614 |
self::_update_option(
|
2615 |
'spam_count',
|
2616 |
+
intval( self::get_option( 'spam_count' ) + 1 )
|
2617 |
);
|
2618 |
}
|
2619 |
|
|
|
2620 |
/**
|
2621 |
+
* Update statistics
|
2622 |
+
*
|
2623 |
+
* @since 1.9
|
2624 |
+
* @change 2.6.1
|
2625 |
+
*/
|
2626 |
+
private static function _update_daily_stats() {
|
2627 |
+
// Skip if not enabled.
|
2628 |
+
if ( ! self::get_option( 'dashboard_chart' ) ) {
|
|
|
|
|
2629 |
return;
|
2630 |
}
|
2631 |
|
2632 |
+
// Init.
|
2633 |
+
$stats = (array) self::get_option( 'daily_stats' );
|
2634 |
+
$today = (int) strtotime( 'today' );
|
2635 |
|
2636 |
+
// Count up.
|
2637 |
+
if ( array_key_exists( $today, $stats ) ) {
|
2638 |
+
$stats[ $today ] ++;
|
2639 |
} else {
|
2640 |
+
$stats[ $today ] = 1;
|
2641 |
}
|
2642 |
|
2643 |
+
// Sort.
|
2644 |
+
krsort( $stats, SORT_NUMERIC );
|
2645 |
|
2646 |
+
// Save.
|
2647 |
self::_update_option(
|
2648 |
'daily_stats',
|
2649 |
+
array_slice( $stats, 0, 31, true )
|
2650 |
);
|
2651 |
}
|
2652 |
|
2653 |
/**
|
2654 |
* Returns the secret of a post used in the textarea name attribute.
|
2655 |
*
|
2656 |
+
* @param int $post_id The Post ID.
|
2657 |
*
|
2658 |
* @return string
|
2659 |
*/
|
2660 |
public static function get_secret_name_for_post( $post_id ) {
|
2661 |
|
2662 |
+
if ( self::get_option( 'always_allowed' ) ) {
|
2663 |
+
$secret = substr( sha1( md5( 'comment-id' . self::$_salt ) ), 0, 10 );
|
2664 |
+
} else {
|
2665 |
+
$secret = substr( sha1( md5( 'comment-id' . self::$_salt . (int) $post_id ) ), 0, 10 );
|
2666 |
+
}
|
2667 |
|
2668 |
/**
|
2669 |
* Filters the secret for a post, which is used in the textarea name attribute.
|
2670 |
*
|
2671 |
* @param string $secret The secret.
|
2672 |
* @param int $post_id The post ID.
|
2673 |
+
* @param bool $always_allowed Whether the comment form is used outside of the single post view or not.
|
2674 |
*/
|
2675 |
return apply_filters(
|
2676 |
'ab_get_secret_name_for_post',
|
2677 |
$secret,
|
2678 |
+
(int) $post_id,
|
2679 |
+
(bool) self::get_option( 'always_allowed' )
|
2680 |
);
|
2681 |
|
2682 |
}
|
2684 |
/**
|
2685 |
* Returns the secret of a post used in the textarea id attribute.
|
2686 |
*
|
2687 |
+
* @param int $post_id The post ID.
|
2688 |
*
|
2689 |
* @return string
|
2690 |
*/
|
2691 |
public static function get_secret_id_for_post( $post_id ) {
|
2692 |
|
2693 |
+
if ( self::get_option( 'always_allowed' ) ) {
|
2694 |
+
$secret = substr( sha1( md5( 'comment-id' . self::$_salt ) ), 0, 10 );
|
2695 |
+
} else {
|
2696 |
+
$secret = substr( sha1( md5( 'comment-id' . self::$_salt . (int) $post_id ) ), 0, 10 );
|
2697 |
+
}
|
2698 |
|
2699 |
/**
|
2700 |
* Filters the secret for a post, which is used in the textarea id attribute.
|
2701 |
*
|
2702 |
* @param string $secret The secret.
|
2703 |
* @param int $post_id The post ID.
|
2704 |
+
* @param bool $always_allowed Whether the comment form is used outside of the single post view or not.
|
2705 |
*/
|
2706 |
return apply_filters(
|
2707 |
'ab_get_secret_id_for_post',
|
2708 |
$secret,
|
2709 |
+
(int) $post_id,
|
2710 |
+
(bool) self::get_option( 'always_allowed' )
|
2711 |
);
|
2712 |
}
|
2713 |
|
2722 |
|
2723 |
return 'spam';
|
2724 |
}
|
2725 |
+
|
2726 |
+
/**
|
2727 |
+
* A wrapper around wp_parse_url().
|
2728 |
+
*
|
2729 |
+
* @since 2.8.2
|
2730 |
+
*
|
2731 |
+
* @param string $url The URL to parse.
|
2732 |
+
* @param string $component The component to get back.
|
2733 |
+
*
|
2734 |
+
* @return string
|
2735 |
+
*/
|
2736 |
+
private static function parse_url( $url, $component = 'host' ) {
|
2737 |
+
|
2738 |
+
$parts = wp_parse_url( $url );
|
2739 |
+
return ( is_array( $parts ) && isset( $parts[ $component ] ) ) ? $parts[ $component ] : '';
|
2740 |
+
}
|
2741 |
}
|
2742 |
|
2743 |
|
2744 |
+
// Fire.
|
2745 |
add_action(
|
2746 |
'plugins_loaded',
|
2747 |
array(
|
2748 |
'Antispam_Bee',
|
2749 |
+
'init',
|
2750 |
)
|
2751 |
);
|
2752 |
|
2753 |
+
// Activation.
|
2754 |
register_activation_hook(
|
2755 |
__FILE__,
|
2756 |
array(
|
2757 |
'Antispam_Bee',
|
2758 |
+
'activate',
|
2759 |
)
|
2760 |
);
|
2761 |
|
2762 |
+
// Deactivation.
|
2763 |
register_deactivation_hook(
|
2764 |
__FILE__,
|
2765 |
array(
|
2766 |
'Antispam_Bee',
|
2767 |
+
'deactivate',
|
2768 |
)
|
2769 |
);
|
2770 |
|
2771 |
+
// Uninstall.
|
2772 |
register_uninstall_hook(
|
2773 |
__FILE__,
|
2774 |
array(
|
2775 |
'Antispam_Bee',
|
2776 |
+
'uninstall',
|
2777 |
)
|
2778 |
);
|
inc/columns.class.php
CHANGED
@@ -1,120 +1,105 @@
|
|
1 |
<?php
|
2 |
-
|
3 |
-
|
4 |
-
|
|
|
|
|
5 |
|
6 |
-
|
7 |
|
|
|
|
|
|
|
8 |
final class Antispam_Bee_Columns {
|
9 |
|
10 |
-
|
11 |
/**
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
public static function register_plugin_columns($columns)
|
22 |
-
{
|
23 |
return array_merge(
|
24 |
$columns,
|
25 |
array(
|
26 |
-
'antispam_bee_reason' => esc_html__('Spam Reason', 'antispam-bee')
|
27 |
)
|
28 |
);
|
29 |
}
|
30 |
|
31 |
-
|
32 |
/**
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
{
|
44 |
-
// Only Antispam Bee column
|
45 |
-
if ( $column !== 'antispam_bee_reason' ) {
|
46 |
return;
|
47 |
}
|
48 |
|
49 |
-
|
50 |
-
$spam_reason = get_comment_meta($comment_id, $column, true);
|
51 |
$spam_reasons = Antispam_Bee::$defaults['reasons'];
|
52 |
|
53 |
-
|
54 |
-
if ( empty($spam_reason) OR empty($spam_reasons[$spam_reason]) ) {
|
55 |
return;
|
56 |
}
|
57 |
|
58 |
-
|
59 |
-
echo esc_html( $spam_reasons[$spam_reason] );
|
60 |
}
|
61 |
|
62 |
-
|
63 |
/**
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
public static function register_sortable_columns($columns)
|
74 |
-
{
|
75 |
$columns['antispam_bee_reason'] = 'antispam_bee_reason';
|
76 |
|
77 |
return $columns;
|
78 |
}
|
79 |
|
80 |
-
|
81 |
/**
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
$orderby = $query->get('orderby');
|
94 |
-
|
95 |
-
// Skip if not our case
|
96 |
-
if ( empty($orderby) OR $orderby !== 'antispam_bee_reason' ) {
|
97 |
return;
|
98 |
}
|
99 |
|
100 |
-
// Set orderby values
|
101 |
$query->set( 'meta_key', 'antispam_bee_reason' );
|
102 |
$query->set( 'orderby', 'meta_value' );
|
103 |
}
|
104 |
|
105 |
-
|
106 |
/**
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
public static function print_column_styles() { ?>
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
|
|
120 |
}
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* The Columns Class.
|
4 |
+
*
|
5 |
+
* @package Antispam Bee
|
6 |
+
*/
|
7 |
|
8 |
+
defined( 'ABSPATH' ) || exit;
|
9 |
|
10 |
+
/**
|
11 |
+
* Class Antispam_Bee_Columns
|
12 |
+
*/
|
13 |
final class Antispam_Bee_Columns {
|
14 |
|
|
|
15 |
/**
|
16 |
+
* Register plugin columns on comments screen.
|
17 |
+
*
|
18 |
+
* @since 2.6.0
|
19 |
+
* @change 2.6.0
|
20 |
+
*
|
21 |
+
* @param array $columns Array with existing columns.
|
22 |
+
* @return array Array with extended columns.
|
23 |
+
*/
|
24 |
+
public static function register_plugin_columns( $columns ) {
|
|
|
|
|
25 |
return array_merge(
|
26 |
$columns,
|
27 |
array(
|
28 |
+
'antispam_bee_reason' => esc_html__( 'Spam Reason', 'antispam-bee' ),
|
29 |
)
|
30 |
);
|
31 |
}
|
32 |
|
|
|
33 |
/**
|
34 |
+
* Display plugin column values on comments screen
|
35 |
+
*
|
36 |
+
* @since 2.6.0
|
37 |
+
* @change 2.6.0
|
38 |
+
*
|
39 |
+
* @param string $column Currently selected column.
|
40 |
+
* @param integer $comment_id Comment ID.
|
41 |
+
*/
|
42 |
+
public static function print_plugin_column( $column, $comment_id ) {
|
43 |
+
if ( 'antispam_bee_reason' !== $column ) {
|
|
|
|
|
|
|
44 |
return;
|
45 |
}
|
46 |
|
47 |
+
$spam_reason = get_comment_meta( $comment_id, $column, true );
|
|
|
48 |
$spam_reasons = Antispam_Bee::$defaults['reasons'];
|
49 |
|
50 |
+
if ( empty( $spam_reason ) || empty( $spam_reasons[ $spam_reason ] ) ) {
|
|
|
51 |
return;
|
52 |
}
|
53 |
|
54 |
+
echo esc_html( $spam_reasons[ $spam_reason ] );
|
|
|
55 |
}
|
56 |
|
|
|
57 |
/**
|
58 |
+
* Register plugin sortable columns on comments screen
|
59 |
+
*
|
60 |
+
* @since 2.6.3
|
61 |
+
* @change 2.6.3
|
62 |
+
*
|
63 |
+
* @param array $columns Registered columns.
|
64 |
+
* @return array $columns Columns with AB field.
|
65 |
+
*/
|
66 |
+
public static function register_sortable_columns( $columns ) {
|
|
|
|
|
67 |
$columns['antispam_bee_reason'] = 'antispam_bee_reason';
|
68 |
|
69 |
return $columns;
|
70 |
}
|
71 |
|
|
|
72 |
/**
|
73 |
+
* Adjust orderby query
|
74 |
+
*
|
75 |
+
* @since 2.6.3
|
76 |
+
* @change 2.6.3
|
77 |
+
*
|
78 |
+
* @param \WP_Query $query Current WordPress query.
|
79 |
+
*/
|
80 |
+
public static function set_orderby_query( $query ) {
|
81 |
+
$orderby = $query->get( 'orderby' );
|
82 |
+
|
83 |
+
if ( empty( $orderby ) || 'antispam_bee_reason' !== $orderby ) {
|
|
|
|
|
|
|
|
|
84 |
return;
|
85 |
}
|
86 |
|
|
|
87 |
$query->set( 'meta_key', 'antispam_bee_reason' );
|
88 |
$query->set( 'orderby', 'meta_value' );
|
89 |
}
|
90 |
|
|
|
91 |
/**
|
92 |
+
* Print CSS for the plugin column
|
93 |
+
*
|
94 |
+
* @since 2.6.1
|
95 |
+
* @change 2.6.1
|
96 |
+
*/
|
|
|
97 |
public static function print_column_styles() { ?>
|
98 |
+
<style>
|
99 |
+
.column-antispam_bee_reason {
|
100 |
+
width: 10%;
|
101 |
+
}
|
102 |
+
</style>
|
103 |
+
<?php
|
104 |
+
}
|
105 |
}
|
inc/gui.class.php
CHANGED
@@ -1,42 +1,38 @@
|
|
1 |
<?php
|
2 |
-
|
3 |
-
|
|
|
|
|
|
|
4 |
|
|
|
5 |
|
6 |
/**
|
7 |
-
* Antispam_Bee_GUI
|
8 |
-
*
|
9 |
-
* @since 2.4
|
10 |
-
*/
|
11 |
-
|
12 |
class Antispam_Bee_GUI extends Antispam_Bee {
|
13 |
|
14 |
-
|
15 |
/**
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
// No POST?
|
25 |
-
if ( empty($_POST) ) {
|
26 |
-
wp_die(esc_html__('Cheatin’ uh?', 'antispam-bee'));
|
27 |
}
|
28 |
|
29 |
-
|
30 |
-
|
31 |
-
wp_die(esc_html__('Cheatin’ uh?', 'antispam-bee'));
|
32 |
}
|
33 |
|
34 |
-
|
35 |
-
check_admin_referer('_antispam_bee__settings_nonce');
|
36 |
|
37 |
-
|
38 |
-
|
39 |
-
if(!is_array($selected_languages_raw)) {
|
40 |
$selected_languages_raw = array();
|
41 |
}
|
42 |
$selected_languages = array();
|
@@ -49,98 +45,92 @@ class Antispam_Bee_GUI extends Antispam_Bee {
|
|
49 |
$selected_languages[] = $value;
|
50 |
}
|
51 |
$options = array(
|
52 |
-
'flag_spam'
|
53 |
-
'email_notify'
|
54 |
-
'cronjob_enable'
|
55 |
-
'cronjob_interval'
|
56 |
-
|
57 |
-
'no_notice'
|
58 |
-
|
59 |
-
'dashboard_count'
|
60 |
-
'dashboard_chart'
|
61 |
-
'advanced_check'
|
62 |
-
'regexp_check'
|
63 |
-
'spam_ip'
|
64 |
-
'already_commented'
|
65 |
-
'time_check'
|
66 |
-
'always_allowed'
|
67 |
-
|
68 |
-
'ignore_pings'
|
69 |
-
'ignore_filter'
|
70 |
-
'ignore_type'
|
71 |
-
|
72 |
-
'reasons_enable'
|
73 |
-
'ignore_reasons'
|
74 |
-
|
75 |
-
'bbcode_check'
|
76 |
-
'gravatar_check'
|
77 |
-
'country_code'
|
78 |
-
'country_black'
|
79 |
-
'country_white'
|
80 |
-
|
81 |
-
'translate_api'
|
82 |
-
'translate_lang'
|
|
|
|
|
|
|
83 |
);
|
84 |
|
85 |
-
foreach( $options['ignore_reasons'] as $key => $val ) {
|
86 |
if ( ! isset( self::$defaults['reasons'][ $val ] ) ) {
|
87 |
unset( $options['ignore_reasons'][ $key ] );
|
88 |
}
|
89 |
}
|
90 |
|
91 |
-
|
92 |
-
if ( empty($options['cronjob_interval']) ) {
|
93 |
$options['cronjob_enable'] = 0;
|
94 |
}
|
95 |
|
96 |
-
|
97 |
-
if ( empty($options['translate_lang']) ) {
|
98 |
$options['translate_api'] = 0;
|
99 |
}
|
100 |
|
101 |
-
|
102 |
-
if ( empty($options['reasons_enable']) ) {
|
103 |
$options['ignore_reasons'] = array();
|
104 |
}
|
105 |
|
106 |
-
|
107 |
-
if ( !empty($options['country_black']) ) {
|
108 |
$options['country_black'] = preg_replace(
|
109 |
'/[^A-Z ,;]/',
|
110 |
'',
|
111 |
-
strtoupper($options['country_black'])
|
112 |
);
|
113 |
}
|
114 |
|
115 |
-
|
116 |
-
if ( !empty($options['country_white']) ) {
|
117 |
$options['country_white'] = preg_replace(
|
118 |
'/[^A-Z ,;]/',
|
119 |
'',
|
120 |
-
strtoupper($options['country_white'])
|
121 |
);
|
122 |
}
|
123 |
|
124 |
-
|
125 |
-
if ( empty($options['country_black']) && empty($options['country_white']) ) {
|
126 |
$options['country_code'] = 0;
|
127 |
}
|
128 |
|
129 |
-
|
130 |
-
if ( $options['cronjob_enable'] && !self::get_option('cronjob_enable') ) {
|
131 |
self::init_scheduled_hook();
|
132 |
-
}
|
133 |
self::clear_scheduled_hook();
|
134 |
}
|
135 |
|
136 |
-
|
137 |
-
self::update_options($options);
|
138 |
|
139 |
-
// Redirect
|
140 |
wp_safe_redirect(
|
141 |
add_query_arg(
|
142 |
array(
|
143 |
-
'updated' => 'true'
|
144 |
),
|
145 |
wp_get_referer()
|
146 |
)
|
@@ -149,30 +139,22 @@ class Antispam_Bee_GUI extends Antispam_Bee {
|
|
149 |
die();
|
150 |
}
|
151 |
|
152 |
-
|
153 |
/**
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
$html = '<select name="' .$name. '">';
|
169 |
-
|
170 |
-
// Loop options
|
171 |
-
foreach( $data as $k => $v) {
|
172 |
-
$html .= '<option value="' .esc_attr($k). '" ' .selected($selected, $k, false). '>' .esc_html( $v ). '</option>';
|
173 |
}
|
174 |
-
|
175 |
-
// Close HTML
|
176 |
$html .= '</select>';
|
177 |
|
178 |
return $html;
|
@@ -180,24 +162,23 @@ class Antispam_Bee_GUI extends Antispam_Bee {
|
|
180 |
|
181 |
|
182 |
/**
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
public static function options_page() { ?>
|
190 |
<div class="wrap" id="ab_main">
|
191 |
<h2>
|
192 |
Antispam Bee
|
193 |
</h2>
|
194 |
|
195 |
-
<form action="<?php echo admin_url('admin-post.php') ?>" method="post">
|
196 |
<input type="hidden" name="action" value="ab_save_changes" />
|
197 |
|
198 |
-
<?php wp_nonce_field('_antispam_bee__settings_nonce') ?>
|
199 |
|
200 |
-
<?php $options = self::get_options() ?>
|
201 |
<div class="ab-wrap">
|
202 |
<!--[if lt IE 9]>
|
203 |
<p class="browsehappy">
|
@@ -215,33 +196,41 @@ class Antispam_Bee_GUI extends Antispam_Bee {
|
|
215 |
|
216 |
<ul>
|
217 |
<li>
|
218 |
-
<input type="checkbox" name="ab_already_commented" id="ab_already_commented" value="1" <?php checked($options['already_commented'], 1) ?> />
|
219 |
<label for="ab_already_commented">
|
220 |
<?php esc_html_e( 'Trust approved commenters', 'antispam-bee' ); ?>
|
221 |
<span><?php esc_html_e( 'No review of already commented users', 'antispam-bee' ); ?></span>
|
222 |
</label>
|
223 |
</li>
|
224 |
|
|
|
225 |
<li>
|
226 |
-
<input type="checkbox" name="ab_gravatar_check" id="ab_gravatar_check" value="1" <?php checked($options['gravatar_check'], 1) ?> />
|
227 |
<label for="ab_gravatar_check">
|
228 |
<?php esc_html_e( 'Trust commenters with a Gravatar', 'antispam-bee' ); ?>
|
229 |
-
<span
|
|
|
|
|
230 |
'<a href="%s" target="_blank" rel="noopener noreferrer">',
|
231 |
-
|
232 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
233 |
);
|
234 |
-
|
235 |
-
|
236 |
-
esc_html__( 'Check if commenter has a Gravatar image. Please note the %1$sprivacy notice%2$s for this option.', 'antispam-bee' ),
|
237 |
-
$link1,
|
238 |
-
'</a>'
|
239 |
-
); ?></span>
|
240 |
</label>
|
241 |
</li>
|
|
|
242 |
|
243 |
<li>
|
244 |
-
<input type="checkbox" name="ab_time_check" id="ab_time_check" value="1" <?php checked($options['time_check'], 1) ?> />
|
245 |
<label for="ab_time_check">
|
246 |
<?php esc_html_e( 'Consider the comment time', 'antispam-bee' ); ?>
|
247 |
<span><?php esc_html_e( 'Not recommended when using page caching', 'antispam-bee' ); ?></span>
|
@@ -249,7 +238,7 @@ class Antispam_Bee_GUI extends Antispam_Bee {
|
|
249 |
</li>
|
250 |
|
251 |
<li>
|
252 |
-
<input type="checkbox" name="ab_bbcode_check" id="ab_bbcode_check" value="1" <?php checked($options['bbcode_check'], 1) ?> />
|
253 |
<label for="ab_bbcode_check">
|
254 |
<?php esc_html_e( 'BBCode is spam', 'antispam-bee' ); ?>
|
255 |
<span><?php esc_html_e( 'Review the comment contents for BBCode links', 'antispam-bee' ); ?></span>
|
@@ -257,7 +246,7 @@ class Antispam_Bee_GUI extends Antispam_Bee {
|
|
257 |
</li>
|
258 |
|
259 |
<li>
|
260 |
-
<input type="checkbox" name="ab_advanced_check" id="ab_advanced_check" value="1" <?php checked($options['advanced_check'], 1) ?> />
|
261 |
<label for="ab_advanced_check">
|
262 |
<?php esc_html_e( 'Validate the ip address of commenters', 'antispam-bee' ); ?>
|
263 |
<span><?php esc_html_e( 'Validation of the IP address used', 'antispam-bee' ); ?></span>
|
@@ -265,7 +254,7 @@ class Antispam_Bee_GUI extends Antispam_Bee {
|
|
265 |
</li>
|
266 |
|
267 |
<li>
|
268 |
-
<input type="checkbox" name="ab_regexp_check" id="ab_regexp_check" value="1" <?php checked($options['regexp_check'], 1) ?> />
|
269 |
<label for="ab_regexp_check">
|
270 |
<?php esc_html_e( 'Use regular expressions', 'antispam-bee' ); ?>
|
271 |
<span><?php esc_html_e( 'Predefined and custom patterns by plugin hook', 'antispam-bee' ); ?></span>
|
@@ -273,7 +262,7 @@ class Antispam_Bee_GUI extends Antispam_Bee {
|
|
273 |
</li>
|
274 |
|
275 |
<li>
|
276 |
-
<input type="checkbox" name="ab_spam_ip" id="ab_spam_ip" value="1" <?php checked($options['spam_ip'], 1) ?> />
|
277 |
<label for="ab_spam_ip">
|
278 |
<?php esc_html_e( 'Look in the local spam database', 'antispam-bee' ); ?>
|
279 |
<span><?php esc_html_e( 'Check for spam data on your own blog', 'antispam-bee' ); ?></span>
|
@@ -281,85 +270,108 @@ class Antispam_Bee_GUI extends Antispam_Bee {
|
|
281 |
</li>
|
282 |
|
283 |
<li>
|
284 |
-
<input type="checkbox" name="ab_country_code" id="ab_country_code" value="1" <?php checked($options['country_code'], 1) ?> />
|
285 |
<label for="ab_country_code">
|
286 |
-
<?php esc_html_e('Block or allow comments from specific countries', 'antispam-bee') ?>
|
287 |
-
<span
|
|
|
|
|
288 |
'<a href="%s" target="_blank" rel="noopener noreferrer">',
|
289 |
-
|
290 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
291 |
);
|
292 |
-
|
293 |
-
|
294 |
-
esc_html__( 'Filtering the requests depending on country. Please note the %1$sprivacy notice%2$s for this option.', 'antispam-bee' ),
|
295 |
-
$link1, '</a>'
|
296 |
-
); ?></span>
|
297 |
</label>
|
298 |
|
299 |
<ul>
|
300 |
-
<?php
|
|
|
301 |
'<a href="%s" target="_blank" rel="noopener noreferrer">',
|
302 |
-
esc_url(
|
303 |
-
'https' )
|
304 |
-
|
|
|
|
|
|
|
305 |
<li>
|
306 |
-
<textarea name="ab_country_black" id="ab_country_black" class="ab-medium-field code" placeholder="<?php esc_attr_e( 'e.g. BF, SG, YE', 'antispam-bee' ); ?>"><?php echo esc_attr($options['country_black']); ?></textarea>
|
307 |
<label for="ab_country_black">
|
308 |
-
<span
|
|
|
309 |
printf(
|
310 |
/* translators: 1: opening <a> tag with link to ISO codes reference. 2: closing </a> tag. */
|
311 |
esc_html__( 'Blacklist %1$sISO Codes%2$s for this option.', 'antispam-bee' ),
|
312 |
-
$iso_codes_link,
|
313 |
-
'</a>'
|
314 |
-
|
|
|
|
|
315 |
</label>
|
316 |
</li>
|
317 |
<li>
|
318 |
-
<textarea name="ab_country_white" id="ab_country_white" class="ab-medium-field code" placeholder="<?php esc_attr_e( 'e.g. BF, SG, YE', 'antispam-bee' ); ?>"><?php echo esc_attr($options['country_white']); ?></textarea>
|
319 |
<label for="ab_country_white">
|
320 |
-
<span
|
|
|
321 |
printf(
|
322 |
/* translators: 1: opening <a> tag with link to ISO codes reference. 2: closing </a> tag. */
|
323 |
esc_html__( 'Whitelist %1$sISO Codes%2$s for this option.', 'antispam-bee' ),
|
324 |
-
$iso_codes_link,
|
325 |
-
'</a>'
|
326 |
-
|
|
|
|
|
327 |
</label>
|
328 |
</li>
|
329 |
</ul>
|
330 |
</li>
|
331 |
|
332 |
<li>
|
333 |
-
<input type="checkbox" name="ab_translate_api" id="ab_translate_api" value="1" <?php checked($options['translate_api'], 1) ?> />
|
334 |
<label for="ab_translate_api">
|
335 |
-
<?php esc_html_e( 'Allow comments only in certain language', 'antispam-bee' ) ?>
|
336 |
-
<span
|
|
|
337 |
$link1 = sprintf(
|
338 |
'<a href="%s" target="_blank" rel="noopener noreferrer">',
|
339 |
-
esc_url(
|
340 |
-
'https' )
|
|
|
|
|
341 |
);
|
342 |
|
343 |
printf(
|
344 |
/* translators: 1: opening <a> tag with link to documentation. 2: closing </a> tag. */
|
345 |
esc_html__( 'Detect and approve only the specified language. Please note the %1$sprivacy notice%2$s for this option.', 'antispam-bee' ),
|
346 |
-
$link1,
|
347 |
-
'</a>'
|
348 |
-
|
|
|
|
|
349 |
</label>
|
350 |
|
351 |
<ul>
|
352 |
<li>
|
353 |
<select multiple name="ab_translate_lang[]">
|
354 |
<?php
|
355 |
-
$lang
|
356 |
$selected_languages = (array) $options['translate_lang'];
|
357 |
-
foreach( $lang as $k => $v ) {
|
|
|
358 |
<option <?php echo in_array( $k, $selected_languages, true ) ? 'selected="selected"' : ''; ?> value="<?php echo esc_attr( $k ); ?>"><?php echo esc_html( $v ); ?></option>
|
|
|
359 |
<?php } ?>
|
360 |
</select>
|
361 |
<label for="ab_translate_lang">
|
362 |
-
<?php esc_html_e('Language', 'antispam-bee') ?>
|
363 |
</label>
|
364 |
</li>
|
365 |
</ul>
|
@@ -367,7 +379,6 @@ class Antispam_Bee_GUI extends Antispam_Bee {
|
|
367 |
</ul>
|
368 |
</div>
|
369 |
|
370 |
-
|
371 |
<div class="ab-column ab-join">
|
372 |
<h3 class="icon advanced">
|
373 |
<?php esc_html_e( 'Advanced', 'antispam-bee' ); ?>
|
@@ -378,7 +389,7 @@ class Antispam_Bee_GUI extends Antispam_Bee {
|
|
378 |
|
379 |
<ul>
|
380 |
<li>
|
381 |
-
<input type="checkbox" name="ab_flag_spam" id="ab_flag_spam" value="1" <?php checked($options['flag_spam'], 1) ?> />
|
382 |
<label for="ab_flag_spam">
|
383 |
<?php esc_html_e( 'Mark as spam, do not delete', 'antispam-bee' ); ?>
|
384 |
<span><?php esc_html_e( 'Keep the spam in my blog.', 'antispam-bee' ); ?></span>
|
@@ -386,7 +397,7 @@ class Antispam_Bee_GUI extends Antispam_Bee {
|
|
386 |
</li>
|
387 |
|
388 |
<li class="ab_flag_spam_child">
|
389 |
-
<input type="checkbox" name="ab_email_notify" id="ab_email_notify" value="1" <?php checked($options['email_notify'], 1) ?> />
|
390 |
<label for="ab_email_notify">
|
391 |
<?php esc_html_e( 'Spam-Notification by email', 'antispam-bee' ); ?>
|
392 |
<span><?php esc_html_e( 'Notify admins by e-mail about incoming spam', 'antispam-bee' ); ?></span>
|
@@ -394,7 +405,7 @@ class Antispam_Bee_GUI extends Antispam_Bee {
|
|
394 |
</li>
|
395 |
|
396 |
<li class="ab_flag_spam_child">
|
397 |
-
<input type="checkbox" name="ab_no_notice" id="ab_no_notice" value="1" <?php checked($options['no_notice'], 1) ?> />
|
398 |
<label for="ab_no_notice">
|
399 |
<?php esc_html_e( 'Do not save the spam reason', 'antispam-bee' ); ?>
|
400 |
<span><?php esc_html_e( 'Spam reason as a table column in the spam overview', 'antispam-bee' ); ?></span>
|
@@ -402,36 +413,45 @@ class Antispam_Bee_GUI extends Antispam_Bee {
|
|
402 |
</li>
|
403 |
|
404 |
<li class="ab_flag_spam_child">
|
405 |
-
<input type="checkbox" name="ab_cronjob_enable" id="ab_cronjob_enable" value="1" <?php checked($options['cronjob_enable'], 1) ?> />
|
406 |
<label for="ab_cronjob_enable">
|
407 |
-
<?php
|
|
|
|
|
408 |
esc_html__( 'Delete existing spam after %s days', 'antispam-bee' ),
|
409 |
-
'<input type="number" min="0" name="ab_cronjob_interval" value="' .esc_attr($options['cronjob_interval']). '" class="ab-mini-field" />'
|
410 |
-
)
|
411 |
-
|
|
|
412 |
</label>
|
413 |
</li>
|
414 |
|
415 |
<li class="ab_flag_spam_child">
|
416 |
-
<input type="checkbox" name="ab_ignore_filter" id="ab_ignore_filter" value="1" <?php checked($options['ignore_filter'], 1) ?> />
|
417 |
<label for="ab_ignore_filter">
|
418 |
-
<?php
|
|
|
|
|
|
|
|
|
419 |
esc_html__( 'Limit approval to %s', 'antispam-bee' ),
|
420 |
self::_build_select(
|
421 |
'ab_ignore_type',
|
422 |
array(
|
423 |
1 => esc_attr__( 'Comments', 'antispam-bee' ),
|
424 |
-
2 => esc_attr__( 'Pings', 'antispam-bee' )
|
425 |
),
|
426 |
$options['ignore_type']
|
427 |
)
|
428 |
-
|
|
|
|
|
429 |
<span><?php esc_html_e( 'Other types of spam will be deleted immediately', 'antispam-bee' ); ?></span>
|
430 |
</label>
|
431 |
</li>
|
432 |
|
433 |
<li class="ab_flag_spam_child">
|
434 |
-
<input type="checkbox" name="ab_reasons_enable" id="ab_reasons_enable" value="1" <?php checked($options['reasons_enable'], 1) ?> />
|
435 |
<label for="ab_reasons_enable">
|
436 |
<?php esc_html_e( 'Delete comments by spam reasons', 'antispam-bee' ); ?>
|
437 |
<span><?php esc_html_e( 'For multiple selections press Ctrl/CMD', 'antispam-bee' ); ?></span>
|
@@ -441,7 +461,7 @@ class Antispam_Bee_GUI extends Antispam_Bee {
|
|
441 |
<li>
|
442 |
<select name="ab_ignore_reasons[]" id="ab_ignore_reasons" size="2" multiple>
|
443 |
<?php foreach ( self::$defaults['reasons'] as $k => $v ) { ?>
|
444 |
-
<option <?php selected(in_array($k, $options['ignore_reasons']), true); ?> value="<?php echo $k ?>"><?php
|
445 |
<?php } ?>
|
446 |
</select>
|
447 |
<label for="ab_ignore_reasons">
|
@@ -450,7 +470,16 @@ class Antispam_Bee_GUI extends Antispam_Bee {
|
|
450 |
</li>
|
451 |
</ul>
|
452 |
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
453 |
</ul>
|
|
|
454 |
</div>
|
455 |
|
456 |
|
@@ -464,7 +493,7 @@ class Antispam_Bee_GUI extends Antispam_Bee {
|
|
464 |
|
465 |
<ul>
|
466 |
<li>
|
467 |
-
<input type="checkbox" name="ab_dashboard_chart" id="ab_dashboard_chart" value="1" <?php checked($options['dashboard_chart'], 1) ?> />
|
468 |
<label for="ab_dashboard_chart">
|
469 |
<?php esc_html_e( 'Generate statistics as a dashboard widget', 'antispam-bee' ); ?>
|
470 |
<span><?php esc_html_e( 'Daily updates of spam detection rate', 'antispam-bee' ); ?></span>
|
@@ -472,7 +501,7 @@ class Antispam_Bee_GUI extends Antispam_Bee {
|
|
472 |
</li>
|
473 |
|
474 |
<li>
|
475 |
-
<input type="checkbox" name="ab_dashboard_count" id="ab_dashboard_count" value="1" <?php checked($options['dashboard_count'], 1) ?> />
|
476 |
<label for="ab_dashboard_count">
|
477 |
<?php esc_html_e( 'Spam counter on the dashboard', 'antispam-bee' ); ?>
|
478 |
<span><?php esc_html_e( 'Amount of identified spam comments', 'antispam-bee' ); ?></span>
|
@@ -480,7 +509,7 @@ class Antispam_Bee_GUI extends Antispam_Bee {
|
|
480 |
</li>
|
481 |
|
482 |
<li>
|
483 |
-
<input type="checkbox" name="ab_ignore_pings" id="ab_ignore_pings" value="1" <?php checked($options['ignore_pings'], 1) ?> />
|
484 |
<label for="ab_ignore_pings">
|
485 |
<?php esc_html_e( 'Do not check trackbacks / pingbacks', 'antispam-bee' ); ?>
|
486 |
<span><?php esc_html_e( 'No spam check for link notifications', 'antispam-bee' ); ?></span>
|
@@ -488,7 +517,7 @@ class Antispam_Bee_GUI extends Antispam_Bee {
|
|
488 |
</li>
|
489 |
|
490 |
<li>
|
491 |
-
<input type="checkbox" name="ab_always_allowed" id="ab_always_allowed" value="1" <?php checked($options['always_allowed'], 1) ?> />
|
492 |
<label for="ab_always_allowed">
|
493 |
<?php esc_html_e( 'Comment form used outside of posts', 'antispam-bee' ); ?>
|
494 |
<span><?php esc_html_e( 'Check for comment forms on archive pages', 'antispam-bee' ); ?></span>
|
@@ -502,13 +531,13 @@ class Antispam_Bee_GUI extends Antispam_Bee {
|
|
502 |
<a href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=TD4AMD2D8EMZW" target="_blank" rel="noopener noreferrer"><?php esc_html_e( 'Donate', 'antispam-bee' ); ?></a>
|
503 |
</p>
|
504 |
<p>
|
505 |
-
<a href="<?php
|
506 |
</p>
|
507 |
<p>
|
508 |
-
<a href="https://github.com/pluginkollektiv/antispam-bee/wiki/" target="_blank" rel="noopener noreferrer"><?php esc_html_e( 'Manual', 'antispam-bee' ); ?></a>
|
509 |
</p>
|
510 |
<p>
|
511 |
-
<a href="https://wordpress.org/support/plugin/antispam-bee" target="_blank" rel="noopener noreferrer"><?php esc_html_e( 'Support', 'antispam-bee' ); ?></a>
|
512 |
</p>
|
513 |
|
514 |
<input type="submit" class="button button-primary" value="<?php esc_html_e( 'Save Changes', 'antispam-bee' ); ?>" />
|
@@ -516,7 +545,8 @@ class Antispam_Bee_GUI extends Antispam_Bee {
|
|
516 |
</div>
|
517 |
</form>
|
518 |
</div>
|
519 |
-
|
|
|
520 |
|
521 |
/**
|
522 |
* Get the languages, which are selectable to restrict the comment language to.
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* The Antispam Bee GUI
|
4 |
+
*
|
5 |
+
* @package Antispam Bee
|
6 |
+
*/
|
7 |
|
8 |
+
defined( 'ABSPATH' ) || exit;
|
9 |
|
10 |
/**
|
11 |
+
* Antispam_Bee_GUI
|
12 |
+
*
|
13 |
+
* @since 2.4
|
14 |
+
*/
|
|
|
15 |
class Antispam_Bee_GUI extends Antispam_Bee {
|
16 |
|
|
|
17 |
/**
|
18 |
+
* Save the GUI
|
19 |
+
*
|
20 |
+
* @since 0.1
|
21 |
+
* @change 2.7.0
|
22 |
+
*/
|
23 |
+
public static function save_changes() {
|
24 |
+
if ( empty( $_POST ) ) {
|
25 |
+
wp_die( esc_html__( 'Cheatin’ uh?', 'antispam-bee' ) );
|
|
|
|
|
|
|
26 |
}
|
27 |
|
28 |
+
if ( ! current_user_can( 'manage_options' ) ) {
|
29 |
+
wp_die( esc_html__( 'Cheatin’ uh?', 'antispam-bee' ) );
|
|
|
30 |
}
|
31 |
|
32 |
+
check_admin_referer( '_antispam_bee__settings_nonce' );
|
|
|
33 |
|
34 |
+
$selected_languages_raw = wp_unslash( self::get_key( $_POST, 'ab_translate_lang' ) );
|
35 |
+
if ( ! is_array( $selected_languages_raw ) ) {
|
|
|
36 |
$selected_languages_raw = array();
|
37 |
}
|
38 |
$selected_languages = array();
|
45 |
$selected_languages[] = $value;
|
46 |
}
|
47 |
$options = array(
|
48 |
+
'flag_spam' => (int) ( ! empty( $_POST['ab_flag_spam'] ) ),
|
49 |
+
'email_notify' => (int) ( ! empty( $_POST['ab_email_notify'] ) ),
|
50 |
+
'cronjob_enable' => (int) ( ! empty( $_POST['ab_cronjob_enable'] ) ),
|
51 |
+
'cronjob_interval' => (int) self::get_key( $_POST, 'ab_cronjob_interval' ),
|
52 |
+
|
53 |
+
'no_notice' => (int) ( ! empty( $_POST['ab_no_notice'] ) ),
|
54 |
+
|
55 |
+
'dashboard_count' => (int) ( ! empty( $_POST['ab_dashboard_count'] ) ),
|
56 |
+
'dashboard_chart' => (int) ( ! empty( $_POST['ab_dashboard_chart'] ) ),
|
57 |
+
'advanced_check' => (int) ( ! empty( $_POST['ab_advanced_check'] ) ),
|
58 |
+
'regexp_check' => (int) ( ! empty( $_POST['ab_regexp_check'] ) ),
|
59 |
+
'spam_ip' => (int) ( ! empty( $_POST['ab_spam_ip'] ) ),
|
60 |
+
'already_commented' => (int) ( ! empty( $_POST['ab_already_commented'] ) ),
|
61 |
+
'time_check' => (int) ( ! empty( $_POST['ab_time_check'] ) ),
|
62 |
+
'always_allowed' => (int) ( ! empty( $_POST['ab_always_allowed'] ) ),
|
63 |
+
|
64 |
+
'ignore_pings' => (int) ( ! empty( $_POST['ab_ignore_pings'] ) ),
|
65 |
+
'ignore_filter' => (int) ( ! empty( $_POST['ab_ignore_filter'] ) ),
|
66 |
+
'ignore_type' => (int) self::get_key( $_POST, 'ab_ignore_type' ),
|
67 |
+
|
68 |
+
'reasons_enable' => (int) ( ! empty( $_POST['ab_reasons_enable'] ) ),
|
69 |
+
'ignore_reasons' => (array) self::get_key( $_POST, 'ab_ignore_reasons' ),
|
70 |
+
|
71 |
+
'bbcode_check' => (int) ( ! empty( $_POST['ab_bbcode_check'] ) ),
|
72 |
+
'gravatar_check' => (int) ( ! empty( $_POST['ab_gravatar_check'] ) ),
|
73 |
+
'country_code' => (int) ( ! empty( $_POST['ab_country_code'] ) ),
|
74 |
+
'country_black' => sanitize_text_field( wp_unslash( self::get_key( $_POST, 'ab_country_black' ) ) ),
|
75 |
+
'country_white' => sanitize_text_field( wp_unslash( self::get_key( $_POST, 'ab_country_white' ) ) ),
|
76 |
+
|
77 |
+
'translate_api' => (int) ( ! empty( $_POST['ab_translate_api'] ) ),
|
78 |
+
'translate_lang' => $selected_languages,
|
79 |
+
|
80 |
+
'delete_data_on_uninstall' => (int) ( ! empty( $_POST['delete_data_on_uninstall'] ) ),
|
81 |
+
|
82 |
);
|
83 |
|
84 |
+
foreach ( $options['ignore_reasons'] as $key => $val ) {
|
85 |
if ( ! isset( self::$defaults['reasons'][ $val ] ) ) {
|
86 |
unset( $options['ignore_reasons'][ $key ] );
|
87 |
}
|
88 |
}
|
89 |
|
90 |
+
if ( empty( $options['cronjob_interval'] ) ) {
|
|
|
91 |
$options['cronjob_enable'] = 0;
|
92 |
}
|
93 |
|
94 |
+
if ( empty( $options['translate_lang'] ) ) {
|
|
|
95 |
$options['translate_api'] = 0;
|
96 |
}
|
97 |
|
98 |
+
if ( empty( $options['reasons_enable'] ) ) {
|
|
|
99 |
$options['ignore_reasons'] = array();
|
100 |
}
|
101 |
|
102 |
+
if ( ! empty( $options['country_black'] ) ) {
|
|
|
103 |
$options['country_black'] = preg_replace(
|
104 |
'/[^A-Z ,;]/',
|
105 |
'',
|
106 |
+
strtoupper( $options['country_black'] )
|
107 |
);
|
108 |
}
|
109 |
|
110 |
+
if ( ! empty( $options['country_white'] ) ) {
|
|
|
111 |
$options['country_white'] = preg_replace(
|
112 |
'/[^A-Z ,;]/',
|
113 |
'',
|
114 |
+
strtoupper( $options['country_white'] )
|
115 |
);
|
116 |
}
|
117 |
|
118 |
+
if ( empty( $options['country_black'] ) && empty( $options['country_white'] ) ) {
|
|
|
119 |
$options['country_code'] = 0;
|
120 |
}
|
121 |
|
122 |
+
if ( $options['cronjob_enable'] && ! self::get_option( 'cronjob_enable' ) ) {
|
|
|
123 |
self::init_scheduled_hook();
|
124 |
+
} elseif ( ! $options['cronjob_enable'] && self::get_option( 'cronjob_enable' ) ) {
|
125 |
self::clear_scheduled_hook();
|
126 |
}
|
127 |
|
128 |
+
self::update_options( $options );
|
|
|
129 |
|
|
|
130 |
wp_safe_redirect(
|
131 |
add_query_arg(
|
132 |
array(
|
133 |
+
'updated' => 'true',
|
134 |
),
|
135 |
wp_get_referer()
|
136 |
)
|
139 |
die();
|
140 |
}
|
141 |
|
|
|
142 |
/**
|
143 |
+
* Generation of a selectbox
|
144 |
+
*
|
145 |
+
* @since 2.4.5
|
146 |
+
* @change 2.4.5
|
147 |
+
*
|
148 |
+
* @param string $name Name of the Selectbox.
|
149 |
+
* @param array $data Array with values.
|
150 |
+
* @param string $selected Selected value.
|
151 |
+
* @return string $html Generated HTML.
|
152 |
+
*/
|
153 |
+
private static function _build_select( $name, $data, $selected ) {
|
154 |
+
$html = '<select name="' . esc_attr( $name ) . '">';
|
155 |
+
foreach ( $data as $k => $v ) {
|
156 |
+
$html .= '<option value="' . esc_attr( $k ) . '" ' . selected( $selected, $k, false ) . '>' . esc_html( $v ) . '</option>';
|
|
|
|
|
|
|
|
|
|
|
157 |
}
|
|
|
|
|
158 |
$html .= '</select>';
|
159 |
|
160 |
return $html;
|
162 |
|
163 |
|
164 |
/**
|
165 |
+
* Display the GUI
|
166 |
+
*
|
167 |
+
* @since 0.1
|
168 |
+
* @change 2.7.0
|
169 |
+
*/
|
|
|
170 |
public static function options_page() { ?>
|
171 |
<div class="wrap" id="ab_main">
|
172 |
<h2>
|
173 |
Antispam Bee
|
174 |
</h2>
|
175 |
|
176 |
+
<form action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" method="post">
|
177 |
<input type="hidden" name="action" value="ab_save_changes" />
|
178 |
|
179 |
+
<?php wp_nonce_field( '_antispam_bee__settings_nonce' ); ?>
|
180 |
|
181 |
+
<?php $options = self::get_options(); ?>
|
182 |
<div class="ab-wrap">
|
183 |
<!--[if lt IE 9]>
|
184 |
<p class="browsehappy">
|
196 |
|
197 |
<ul>
|
198 |
<li>
|
199 |
+
<input type="checkbox" name="ab_already_commented" id="ab_already_commented" value="1" <?php checked( $options['already_commented'], 1 ); ?> />
|
200 |
<label for="ab_already_commented">
|
201 |
<?php esc_html_e( 'Trust approved commenters', 'antispam-bee' ); ?>
|
202 |
<span><?php esc_html_e( 'No review of already commented users', 'antispam-bee' ); ?></span>
|
203 |
</label>
|
204 |
</li>
|
205 |
|
206 |
+
<?php if ( 1 === (int) get_option( 'show_avatars', 0 ) ) : ?>
|
207 |
<li>
|
208 |
+
<input type="checkbox" name="ab_gravatar_check" id="ab_gravatar_check" value="1" <?php checked( $options['gravatar_check'], 1 ); ?> />
|
209 |
<label for="ab_gravatar_check">
|
210 |
<?php esc_html_e( 'Trust commenters with a Gravatar', 'antispam-bee' ); ?>
|
211 |
+
<span>
|
212 |
+
<?php
|
213 |
+
$link1 = sprintf(
|
214 |
'<a href="%s" target="_blank" rel="noopener noreferrer">',
|
215 |
+
esc_url(
|
216 |
+
__( 'https://github.com/pluginkollektiv/antispam-bee/wiki/en-Documentation#trust-commenters-with-a-gravatar', 'antispam-bee' ),
|
217 |
+
'https'
|
218 |
+
)
|
219 |
+
);
|
220 |
+
printf(
|
221 |
+
/* translators: 1: opening <a> tag with link to documentation. 2: closing </a> tag */
|
222 |
+
esc_html__( 'Check if commenter has a Gravatar image. Please note the %1$sprivacy notice%2$s for this option.', 'antispam-bee' ),
|
223 |
+
wp_kses_post( $link1 ),
|
224 |
+
'</a>'
|
225 |
);
|
226 |
+
?>
|
227 |
+
</span>
|
|
|
|
|
|
|
|
|
228 |
</label>
|
229 |
</li>
|
230 |
+
<?php endif; ?>
|
231 |
|
232 |
<li>
|
233 |
+
<input type="checkbox" name="ab_time_check" id="ab_time_check" value="1" <?php checked( $options['time_check'], 1 ); ?> />
|
234 |
<label for="ab_time_check">
|
235 |
<?php esc_html_e( 'Consider the comment time', 'antispam-bee' ); ?>
|
236 |
<span><?php esc_html_e( 'Not recommended when using page caching', 'antispam-bee' ); ?></span>
|
238 |
</li>
|
239 |
|
240 |
<li>
|
241 |
+
<input type="checkbox" name="ab_bbcode_check" id="ab_bbcode_check" value="1" <?php checked( $options['bbcode_check'], 1 ); ?> />
|
242 |
<label for="ab_bbcode_check">
|
243 |
<?php esc_html_e( 'BBCode is spam', 'antispam-bee' ); ?>
|
244 |
<span><?php esc_html_e( 'Review the comment contents for BBCode links', 'antispam-bee' ); ?></span>
|
246 |
</li>
|
247 |
|
248 |
<li>
|
249 |
+
<input type="checkbox" name="ab_advanced_check" id="ab_advanced_check" value="1" <?php checked( $options['advanced_check'], 1 ); ?> />
|
250 |
<label for="ab_advanced_check">
|
251 |
<?php esc_html_e( 'Validate the ip address of commenters', 'antispam-bee' ); ?>
|
252 |
<span><?php esc_html_e( 'Validation of the IP address used', 'antispam-bee' ); ?></span>
|
254 |
</li>
|
255 |
|
256 |
<li>
|
257 |
+
<input type="checkbox" name="ab_regexp_check" id="ab_regexp_check" value="1" <?php checked( $options['regexp_check'], 1 ); ?> />
|
258 |
<label for="ab_regexp_check">
|
259 |
<?php esc_html_e( 'Use regular expressions', 'antispam-bee' ); ?>
|
260 |
<span><?php esc_html_e( 'Predefined and custom patterns by plugin hook', 'antispam-bee' ); ?></span>
|
262 |
</li>
|
263 |
|
264 |
<li>
|
265 |
+
<input type="checkbox" name="ab_spam_ip" id="ab_spam_ip" value="1" <?php checked( $options['spam_ip'], 1 ); ?> />
|
266 |
<label for="ab_spam_ip">
|
267 |
<?php esc_html_e( 'Look in the local spam database', 'antispam-bee' ); ?>
|
268 |
<span><?php esc_html_e( 'Check for spam data on your own blog', 'antispam-bee' ); ?></span>
|
270 |
</li>
|
271 |
|
272 |
<li>
|
273 |
+
<input type="checkbox" name="ab_country_code" id="ab_country_code" value="1" <?php checked( $options['country_code'], 1 ); ?> />
|
274 |
<label for="ab_country_code">
|
275 |
+
<?php esc_html_e( 'Block or allow comments from specific countries', 'antispam-bee' ); ?>
|
276 |
+
<span>
|
277 |
+
<?php
|
278 |
+
$link1 = sprintf(
|
279 |
'<a href="%s" target="_blank" rel="noopener noreferrer">',
|
280 |
+
esc_url(
|
281 |
+
__( 'https://github.com/pluginkollektiv/antispam-bee/wiki/en-Documentation#block-comments-from-specific-countries', 'antispam-bee' ),
|
282 |
+
'https'
|
283 |
+
)
|
284 |
+
);
|
285 |
+
printf(
|
286 |
+
/* translators: 1: opening <a> tag with link to documentation. 2: closing </a> tag. */
|
287 |
+
esc_html__( 'Filtering the requests depending on country. Please note the %1$sprivacy notice%2$s for this option.', 'antispam-bee' ),
|
288 |
+
wp_kses_post( $link1 ), '</a>'
|
289 |
);
|
290 |
+
?>
|
291 |
+
</span>
|
|
|
|
|
|
|
292 |
</label>
|
293 |
|
294 |
<ul>
|
295 |
+
<?php
|
296 |
+
$iso_codes_link = sprintf(
|
297 |
'<a href="%s" target="_blank" rel="noopener noreferrer">',
|
298 |
+
esc_url(
|
299 |
+
__( 'https://www.iso.org/iso/country_names_and_code_elements', 'antispam-bee' ),
|
300 |
+
'https'
|
301 |
+
)
|
302 |
+
);
|
303 |
+
?>
|
304 |
<li>
|
305 |
+
<textarea name="ab_country_black" id="ab_country_black" class="ab-medium-field code" placeholder="<?php esc_attr_e( 'e.g. BF, SG, YE', 'antispam-bee' ); ?>"><?php echo esc_attr( $options['country_black'] ); ?></textarea>
|
306 |
<label for="ab_country_black">
|
307 |
+
<span>
|
308 |
+
<?php
|
309 |
printf(
|
310 |
/* translators: 1: opening <a> tag with link to ISO codes reference. 2: closing </a> tag. */
|
311 |
esc_html__( 'Blacklist %1$sISO Codes%2$s for this option.', 'antispam-bee' ),
|
312 |
+
wp_kses_post( $iso_codes_link ),
|
313 |
+
'</a>'
|
314 |
+
);
|
315 |
+
?>
|
316 |
+
</span>
|
317 |
</label>
|
318 |
</li>
|
319 |
<li>
|
320 |
+
<textarea name="ab_country_white" id="ab_country_white" class="ab-medium-field code" placeholder="<?php esc_attr_e( 'e.g. BF, SG, YE', 'antispam-bee' ); ?>"><?php echo esc_attr( $options['country_white'] ); ?></textarea>
|
321 |
<label for="ab_country_white">
|
322 |
+
<span>
|
323 |
+
<?php
|
324 |
printf(
|
325 |
/* translators: 1: opening <a> tag with link to ISO codes reference. 2: closing </a> tag. */
|
326 |
esc_html__( 'Whitelist %1$sISO Codes%2$s for this option.', 'antispam-bee' ),
|
327 |
+
wp_kses_post( $iso_codes_link ),
|
328 |
+
'</a>'
|
329 |
+
);
|
330 |
+
?>
|
331 |
+
</span>
|
332 |
</label>
|
333 |
</li>
|
334 |
</ul>
|
335 |
</li>
|
336 |
|
337 |
<li>
|
338 |
+
<input type="checkbox" name="ab_translate_api" id="ab_translate_api" value="1" <?php checked( $options['translate_api'], 1 ); ?> />
|
339 |
<label for="ab_translate_api">
|
340 |
+
<?php esc_html_e( 'Allow comments only in certain language', 'antispam-bee' ); ?>
|
341 |
+
<span>
|
342 |
+
<?php
|
343 |
$link1 = sprintf(
|
344 |
'<a href="%s" target="_blank" rel="noopener noreferrer">',
|
345 |
+
esc_url(
|
346 |
+
__( 'https://github.com/pluginkollektiv/antispam-bee/wiki/en-Documentation#allow-comments-only-in-certain-language', 'antispam-bee' ),
|
347 |
+
'https'
|
348 |
+
)
|
349 |
);
|
350 |
|
351 |
printf(
|
352 |
/* translators: 1: opening <a> tag with link to documentation. 2: closing </a> tag. */
|
353 |
esc_html__( 'Detect and approve only the specified language. Please note the %1$sprivacy notice%2$s for this option.', 'antispam-bee' ),
|
354 |
+
wp_kses_post( $link1 ),
|
355 |
+
'</a>'
|
356 |
+
);
|
357 |
+
?>
|
358 |
+
</span>
|
359 |
</label>
|
360 |
|
361 |
<ul>
|
362 |
<li>
|
363 |
<select multiple name="ab_translate_lang[]">
|
364 |
<?php
|
365 |
+
$lang = self::get_allowed_translate_languages();
|
366 |
$selected_languages = (array) $options['translate_lang'];
|
367 |
+
foreach ( $lang as $k => $v ) {
|
368 |
+
?>
|
369 |
<option <?php echo in_array( $k, $selected_languages, true ) ? 'selected="selected"' : ''; ?> value="<?php echo esc_attr( $k ); ?>"><?php echo esc_html( $v ); ?></option>
|
370 |
+
|
371 |
<?php } ?>
|
372 |
</select>
|
373 |
<label for="ab_translate_lang">
|
374 |
+
<?php esc_html_e( 'Language', 'antispam-bee' ); ?>
|
375 |
</label>
|
376 |
</li>
|
377 |
</ul>
|
379 |
</ul>
|
380 |
</div>
|
381 |
|
|
|
382 |
<div class="ab-column ab-join">
|
383 |
<h3 class="icon advanced">
|
384 |
<?php esc_html_e( 'Advanced', 'antispam-bee' ); ?>
|
389 |
|
390 |
<ul>
|
391 |
<li>
|
392 |
+
<input type="checkbox" name="ab_flag_spam" id="ab_flag_spam" value="1" <?php checked( $options['flag_spam'], 1 ); ?> />
|
393 |
<label for="ab_flag_spam">
|
394 |
<?php esc_html_e( 'Mark as spam, do not delete', 'antispam-bee' ); ?>
|
395 |
<span><?php esc_html_e( 'Keep the spam in my blog.', 'antispam-bee' ); ?></span>
|
397 |
</li>
|
398 |
|
399 |
<li class="ab_flag_spam_child">
|
400 |
+
<input type="checkbox" name="ab_email_notify" id="ab_email_notify" value="1" <?php checked( $options['email_notify'], 1 ); ?> />
|
401 |
<label for="ab_email_notify">
|
402 |
<?php esc_html_e( 'Spam-Notification by email', 'antispam-bee' ); ?>
|
403 |
<span><?php esc_html_e( 'Notify admins by e-mail about incoming spam', 'antispam-bee' ); ?></span>
|
405 |
</li>
|
406 |
|
407 |
<li class="ab_flag_spam_child">
|
408 |
+
<input type="checkbox" name="ab_no_notice" id="ab_no_notice" value="1" <?php checked( $options['no_notice'], 1 ); ?> />
|
409 |
<label for="ab_no_notice">
|
410 |
<?php esc_html_e( 'Do not save the spam reason', 'antispam-bee' ); ?>
|
411 |
<span><?php esc_html_e( 'Spam reason as a table column in the spam overview', 'antispam-bee' ); ?></span>
|
413 |
</li>
|
414 |
|
415 |
<li class="ab_flag_spam_child">
|
416 |
+
<input type="checkbox" name="ab_cronjob_enable" id="ab_cronjob_enable" value="1" <?php checked( $options['cronjob_enable'], 1 ); ?> />
|
417 |
<label for="ab_cronjob_enable">
|
418 |
+
<?php
|
419 |
+
echo sprintf(
|
420 |
+
// translators: $s is an input field containing the number of days.
|
421 |
esc_html__( 'Delete existing spam after %s days', 'antispam-bee' ),
|
422 |
+
'<input type="number" min="0" name="ab_cronjob_interval" value="' . esc_attr( $options['cronjob_interval'] ) . '" class="ab-mini-field" />'
|
423 |
+
)
|
424 |
+
?>
|
425 |
+
<span><?php esc_html_e( 'Cleaning up the database from old entries', 'antispam-bee' ); ?></span>
|
426 |
</label>
|
427 |
</li>
|
428 |
|
429 |
<li class="ab_flag_spam_child">
|
430 |
+
<input type="checkbox" name="ab_ignore_filter" id="ab_ignore_filter" value="1" <?php checked( $options['ignore_filter'], 1 ); ?> />
|
431 |
<label for="ab_ignore_filter">
|
432 |
+
<?php
|
433 |
+
echo sprintf(
|
434 |
+
// phpcs:disable WordPress.XSS.EscapeOutput.OutputNotEscaped
|
435 |
+
// Output gets escaped in _build_select()
|
436 |
+
// translators: %s is the select field.
|
437 |
esc_html__( 'Limit approval to %s', 'antispam-bee' ),
|
438 |
self::_build_select(
|
439 |
'ab_ignore_type',
|
440 |
array(
|
441 |
1 => esc_attr__( 'Comments', 'antispam-bee' ),
|
442 |
+
2 => esc_attr__( 'Pings', 'antispam-bee' ),
|
443 |
),
|
444 |
$options['ignore_type']
|
445 |
)
|
446 |
+
// phpcs:enable _build_select
|
447 |
+
);
|
448 |
+
?>
|
449 |
<span><?php esc_html_e( 'Other types of spam will be deleted immediately', 'antispam-bee' ); ?></span>
|
450 |
</label>
|
451 |
</li>
|
452 |
|
453 |
<li class="ab_flag_spam_child">
|
454 |
+
<input type="checkbox" name="ab_reasons_enable" id="ab_reasons_enable" value="1" <?php checked( $options['reasons_enable'], 1 ); ?> />
|
455 |
<label for="ab_reasons_enable">
|
456 |
<?php esc_html_e( 'Delete comments by spam reasons', 'antispam-bee' ); ?>
|
457 |
<span><?php esc_html_e( 'For multiple selections press Ctrl/CMD', 'antispam-bee' ); ?></span>
|
461 |
<li>
|
462 |
<select name="ab_ignore_reasons[]" id="ab_ignore_reasons" size="2" multiple>
|
463 |
<?php foreach ( self::$defaults['reasons'] as $k => $v ) { ?>
|
464 |
+
<option <?php selected( in_array( $k, $options['ignore_reasons'], true ), true ); ?> value="<?php echo esc_attr( $k ); ?>"><?php echo esc_html( $v ); ?></option>
|
465 |
<?php } ?>
|
466 |
</select>
|
467 |
<label for="ab_ignore_reasons">
|
470 |
</li>
|
471 |
</ul>
|
472 |
</li>
|
473 |
+
|
474 |
+
<li class="delete_data_on_uninstall">
|
475 |
+
<input type="checkbox" name="delete_data_on_uninstall" id="delete_data_on_uninstall" value="1" <?php checked( $options['delete_data_on_uninstall'], 1 ); ?> />
|
476 |
+
<label for="delete_data_on_uninstall">
|
477 |
+
<?php esc_html_e( 'Delete Antispam Bee data when uninstalling', 'antispam-bee' ); ?>
|
478 |
+
<span><?php esc_html_e( 'If checked, you will delete all data Antispam Bee creates, when uninstalling the plugin.', 'antispam-bee' ); ?></span>
|
479 |
+
</label>
|
480 |
+
</li>
|
481 |
</ul>
|
482 |
+
|
483 |
</div>
|
484 |
|
485 |
|
493 |
|
494 |
<ul>
|
495 |
<li>
|
496 |
+
<input type="checkbox" name="ab_dashboard_chart" id="ab_dashboard_chart" value="1" <?php checked( $options['dashboard_chart'], 1 ); ?> />
|
497 |
<label for="ab_dashboard_chart">
|
498 |
<?php esc_html_e( 'Generate statistics as a dashboard widget', 'antispam-bee' ); ?>
|
499 |
<span><?php esc_html_e( 'Daily updates of spam detection rate', 'antispam-bee' ); ?></span>
|
501 |
</li>
|
502 |
|
503 |
<li>
|
504 |
+
<input type="checkbox" name="ab_dashboard_count" id="ab_dashboard_count" value="1" <?php checked( $options['dashboard_count'], 1 ); ?> />
|
505 |
<label for="ab_dashboard_count">
|
506 |
<?php esc_html_e( 'Spam counter on the dashboard', 'antispam-bee' ); ?>
|
507 |
<span><?php esc_html_e( 'Amount of identified spam comments', 'antispam-bee' ); ?></span>
|
509 |
</li>
|
510 |
|
511 |
<li>
|
512 |
+
<input type="checkbox" name="ab_ignore_pings" id="ab_ignore_pings" value="1" <?php checked( $options['ignore_pings'], 1 ); ?> />
|
513 |
<label for="ab_ignore_pings">
|
514 |
<?php esc_html_e( 'Do not check trackbacks / pingbacks', 'antispam-bee' ); ?>
|
515 |
<span><?php esc_html_e( 'No spam check for link notifications', 'antispam-bee' ); ?></span>
|
517 |
</li>
|
518 |
|
519 |
<li>
|
520 |
+
<input type="checkbox" name="ab_always_allowed" id="ab_always_allowed" value="1" <?php checked( $options['always_allowed'], 1 ); ?> />
|
521 |
<label for="ab_always_allowed">
|
522 |
<?php esc_html_e( 'Comment form used outside of posts', 'antispam-bee' ); ?>
|
523 |
<span><?php esc_html_e( 'Check for comment forms on archive pages', 'antispam-bee' ); ?></span>
|
531 |
<a href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=TD4AMD2D8EMZW" target="_blank" rel="noopener noreferrer"><?php esc_html_e( 'Donate', 'antispam-bee' ); ?></a>
|
532 |
</p>
|
533 |
<p>
|
534 |
+
<a href="<?php echo esc_url( __( 'https://wordpress.org/plugins/antispam-bee/faq/', 'antispam-bee' ) ); ?>" target="_blank" rel="noopener noreferrer"><?php esc_html_e( 'FAQ', 'antispam-bee' ); ?></a>
|
535 |
</p>
|
536 |
<p>
|
537 |
+
<a href="<?php echo esc_url( __( 'https://github.com/pluginkollektiv/antispam-bee/wiki/', 'antispam-bee' ) ); ?>" target="_blank" rel="noopener noreferrer"><?php esc_html_e( 'Manual', 'antispam-bee' ); ?></a>
|
538 |
</p>
|
539 |
<p>
|
540 |
+
<a href="<?php echo esc_url( __( 'https://wordpress.org/support/plugin/antispam-bee', 'antispam-bee' ) ); ?>" target="_blank" rel="noopener noreferrer"><?php esc_html_e( 'Support', 'antispam-bee' ); ?></a>
|
541 |
</p>
|
542 |
|
543 |
<input type="submit" class="button button-primary" value="<?php esc_html_e( 'Save Changes', 'antispam-bee' ); ?>" />
|
545 |
</div>
|
546 |
</form>
|
547 |
</div>
|
548 |
+
<?php
|
549 |
+
}
|
550 |
|
551 |
/**
|
552 |
* Get the languages, which are selectable to restrict the comment language to.
|
js/raphael.min.js
CHANGED
@@ -1,10 +1,3 @@
|
|
1 |
-
// ┌────────────────────────────────────────────────────────────────────┐ \\
|
2 |
-
// │ Raphaël 2.1.0 - JavaScript Vector Library │ \\
|
3 |
-
// ├────────────────────────────────────────────────────────────────────┤ \\
|
4 |
-
// │ Copyright © 2008-2012 Dmitry Baranovskiy (http://raphaeljs.com) │ \\
|
5 |
-
// │ Copyright © 2008-2012 Sencha Labs (http://sencha.com) │ \\
|
6 |
-
// ├────────────────────────────────────────────────────────────────────┤ \\
|
7 |
-
// │ Licensed under the MIT (http://raphaeljs.com/license.html) license.│ \\
|
8 |
-
// └────────────────────────────────────────────────────────────────────┘ \\
|
9 |
-
|
10 |
-
(function(a){var b="0.3.4",c="hasOwnProperty",d=/[\.\/]/,e="*",f=function(){},g=function(a,b){return a-b},h,i,j={n:{}},k=function(a,b){var c=j,d=i,e=Array.prototype.slice.call(arguments,2),f=k.listeners(a),l=0,m=!1,n,o=[],p={},q=[],r=h,s=[];h=a,i=0;for(var t=0,u=f.length;t<u;t++)"zIndex"in f[t]&&(o.push(f[t].zIndex),f[t].zIndex<0&&(p[f[t].zIndex]=f[t]));o.sort(g);while(o[l]<0){n=p[o[l++]],q.push(n.apply(b,e));if(i){i=d;return q}}for(t=0;t<u;t++){n=f[t];if("zIndex"in n)if(n.zIndex==o[l]){q.push(n.apply(b,e));if(i)break;do{l++,n=p[o[l]],n&&q.push(n.apply(b,e));if(i)break}while(n)}else p[n.zIndex]=n;else{q.push(n.apply(b,e));if(i)break}}i=d,h=r;return q.length?q:null};k.listeners=function(a){var b=a.split(d),c=j,f,g,h,i,k,l,m,n,o=[c],p=[];for(i=0,k=b.length;i<k;i++){n=[];for(l=0,m=o.length;l<m;l++){c=o[l].n,g=[c[b[i]],c[e]],h=2;while(h--)f=g[h],f&&(n.push(f),p=p.concat(f.f||[]))}o=n}return p},k.on=function(a,b){var c=a.split(d),e=j;for(var g=0,h=c.length;g<h;g++)e=e.n,!e[c[g]]&&(e[c[g]]={n:{}}),e=e[c[g]];e.f=e.f||[];for(g=0,h=e.f.length;g<h;g++)if(e.f[g]==b)return f;e.f.push(b);return function(a){+a==+a&&(b.zIndex=+a)}},k.stop=function(){i=1},k.nt=function(a){if(a)return(new RegExp("(?:\\.|\\/|^)"+a+"(?:\\.|\\/|$)")).test(h);return h},k.off=k.unbind=function(a,b){var f=a.split(d),g,h,i,k,l,m,n,o=[j];for(k=0,l=f.length;k<l;k++)for(m=0;m<o.length;m+=i.length-2){i=[m,1],g=o[m].n;if(f[k]!=e)g[f[k]]&&i.push(g[f[k]]);else for(h in g)g[c](h)&&i.push(g[h]);o.splice.apply(o,i)}for(k=0,l=o.length;k<l;k++){g=o[k];while(g.n){if(b){if(g.f){for(m=0,n=g.f.length;m<n;m++)if(g.f[m]==b){g.f.splice(m,1);break}!g.f.length&&delete g.f}for(h in g.n)if(g.n[c](h)&&g.n[h].f){var p=g.n[h].f;for(m=0,n=p.length;m<n;m++)if(p[m]==b){p.splice(m,1);break}!p.length&&delete g.n[h].f}}else{delete g.f;for(h in g.n)g.n[c](h)&&g.n[h].f&&delete g.n[h].f}g=g.n}}},k.once=function(a,b){var c=function(){var d=b.apply(this,arguments);k.unbind(a,c);return d};return k.on(a,c)},k.version=b,k.toString=function(){return"You are running Eve "+b},typeof module!="undefined"&&module.exports?module.exports=k:typeof define!="undefined"?define("eve",[],function(){return k}):a.eve=k})(this),function(){function cF(a){for(var b=0;b<cy.length;b++)cy[b].el.paper==a&&cy.splice(b--,1)}function cE(b,d,e,f,h,i){e=Q(e);var j,k,l,m=[],o,p,q,t=b.ms,u={},v={},w={};if(f)for(y=0,z=cy.length;y<z;y++){var x=cy[y];if(x.el.id==d.id&&x.anim==b){x.percent!=e?(cy.splice(y,1),l=1):k=x,d.attr(x.totalOrigin);break}}else f=+v;for(var y=0,z=b.percents.length;y<z;y++){if(b.percents[y]==e||b.percents[y]>f*b.top){e=b.percents[y],p=b.percents[y-1]||0,t=t/b.top*(e-p),o=b.percents[y+1],j=b.anim[e];break}f&&d.attr(b.anim[b.percents[y]])}if(!!j){if(!k){for(var A in j)if(j[g](A))if(U[g](A)||d.paper.customAttributes[g](A)){u[A]=d.attr(A),u[A]==null&&(u[A]=T[A]),v[A]=j[A];switch(U[A]){case C:w[A]=(v[A]-u[A])/t;break;case"colour":u[A]=a.getRGB(u[A]);var B=a.getRGB(v[A]);w[A]={r:(B.r-u[A].r)/t,g:(B.g-u[A].g)/t,b:(B.b-u[A].b)/t};break;case"path":var D=bR(u[A],v[A]),E=D[1];u[A]=D[0],w[A]=[];for(y=0,z=u[A].length;y<z;y++){w[A][y]=[0];for(var F=1,G=u[A][y].length;F<G;F++)w[A][y][F]=(E[y][F]-u[A][y][F])/t}break;case"transform":var H=d._,I=ca(H[A],v[A]);if(I){u[A]=I.from,v[A]=I.to,w[A]=[],w[A].real=!0;for(y=0,z=u[A].length;y<z;y++){w[A][y]=[u[A][y][0]];for(F=1,G=u[A][y].length;F<G;F++)w[A][y][F]=(v[A][y][F]-u[A][y][F])/t}}else{var J=d.matrix||new cb,K={_:{transform:H.transform},getBBox:function(){return d.getBBox(1)}};u[A]=[J.a,J.b,J.c,J.d,J.e,J.f],b$(K,v[A]),v[A]=K._.transform,w[A]=[(K.matrix.a-J.a)/t,(K.matrix.b-J.b)/t,(K.matrix.c-J.c)/t,(K.matrix.d-J.d)/t,(K.matrix.e-J.e)/t,(K.matrix.f-J.f)/t]}break;case"csv":var L=r(j[A])[s](c),M=r(u[A])[s](c);if(A=="clip-rect"){u[A]=M,w[A]=[],y=M.length;while(y--)w[A][y]=(L[y]-u[A][y])/t}v[A]=L;break;default:L=[][n](j[A]),M=[][n](u[A]),w[A]=[],y=d.paper.customAttributes[A].length;while(y--)w[A][y]=((L[y]||0)-(M[y]||0))/t}}var O=j.easing,P=a.easing_formulas[O];if(!P){P=r(O).match(N);if(P&&P.length==5){var R=P;P=function(a){return cC(a,+R[1],+R[2],+R[3],+R[4],t)}}else P=bf}q=j.start||b.start||+(new Date),x={anim:b,percent:e,timestamp:q,start:q+(b.del||0),status:0,initstatus:f||0,stop:!1,ms:t,easing:P,from:u,diff:w,to:v,el:d,callback:j.callback,prev:p,next:o,repeat:i||b.times,origin:d.attr(),totalOrigin:h},cy.push(x);if(f&&!k&&!l){x.stop=!0,x.start=new Date-t*f;if(cy.length==1)return cA()}l&&(x.start=new Date-x.ms*f),cy.length==1&&cz(cA)}else k.initstatus=f,k.start=new Date-k.ms*f;eve("raphael.anim.start."+d.id,d,b)}}function cD(a,b){var c=[],d={};this.ms=b,this.times=1;if(a){for(var e in a)a[g](e)&&(d[Q(e)]=a[e],c.push(Q(e)));c.sort(bd)}this.anim=d,this.top=c[c.length-1],this.percents=c}function cC(a,b,c,d,e,f){function o(a,b){var c,d,e,f,j,k;for(e=a,k=0;k<8;k++){f=m(e)-a;if(z(f)<b)return e;j=(3*i*e+2*h)*e+g;if(z(j)<1e-6)break;e=e-f/j}c=0,d=1,e=a;if(e<c)return c;if(e>d)return d;while(c<d){f=m(e);if(z(f-a)<b)return e;a>f?c=e:d=e,e=(d-c)/2+c}return e}function n(a,b){var c=o(a,b);return((l*c+k)*c+j)*c}function m(a){return((i*a+h)*a+g)*a}var g=3*b,h=3*(d-b)-g,i=1-g-h,j=3*c,k=3*(e-c)-j,l=1-j-k;return n(a,1/(200*f))}function cq(){return this.x+q+this.y+q+this.width+" × "+this.height}function cp(){return this.x+q+this.y}function cb(a,b,c,d,e,f){a!=null?(this.a=+a,this.b=+b,this.c=+c,this.d=+d,this.e=+e,this.f=+f):(this.a=1,this.b=0,this.c=0,this.d=1,this.e=0,this.f=0)}function bH(b,c,d){b=a._path2curve(b),c=a._path2curve(c);var e,f,g,h,i,j,k,l,m,n,o=d?0:[];for(var p=0,q=b.length;p<q;p++){var r=b[p];if(r[0]=="M")e=i=r[1],f=j=r[2];else{r[0]=="C"?(m=[e,f].concat(r.slice(1)),e=m[6],f=m[7]):(m=[e,f,e,f,i,j,i,j],e=i,f=j);for(var s=0,t=c.length;s<t;s++){var u=c[s];if(u[0]=="M")g=k=u[1],h=l=u[2];else{u[0]=="C"?(n=[g,h].concat(u.slice(1)),g=n[6],h=n[7]):(n=[g,h,g,h,k,l,k,l],g=k,h=l);var v=bG(m,n,d);if(d)o+=v;else{for(var w=0,x=v.length;w<x;w++)v[w].segment1=p,v[w].segment2=s,v[w].bez1=m,v[w].bez2=n;o=o.concat(v)}}}}}return o}function bG(b,c,d){var e=a.bezierBBox(b),f=a.bezierBBox(c);if(!a.isBBoxIntersect(e,f))return d?0:[];var g=bB.apply(0,b),h=bB.apply(0,c),i=~~(g/5),j=~~(h/5),k=[],l=[],m={},n=d?0:[];for(var o=0;o<i+1;o++){var p=a.findDotsAtSegment.apply(a,b.concat(o/i));k.push({x:p.x,y:p.y,t:o/i})}for(o=0;o<j+1;o++)p=a.findDotsAtSegment.apply(a,c.concat(o/j)),l.push({x:p.x,y:p.y,t:o/j});for(o=0;o<i;o++)for(var q=0;q<j;q++){var r=k[o],s=k[o+1],t=l[q],u=l[q+1],v=z(s.x-r.x)<.001?"y":"x",w=z(u.x-t.x)<.001?"y":"x",x=bD(r.x,r.y,s.x,s.y,t.x,t.y,u.x,u.y);if(x){if(m[x.x.toFixed(4)]==x.y.toFixed(4))continue;m[x.x.toFixed(4)]=x.y.toFixed(4);var y=r.t+z((x[v]-r[v])/(s[v]-r[v]))*(s.t-r.t),A=t.t+z((x[w]-t[w])/(u[w]-t[w]))*(u.t-t.t);y>=0&&y<=1&&A>=0&&A<=1&&(d?n++:n.push({x:x.x,y:x.y,t1:y,t2:A}))}}return n}function bF(a,b){return bG(a,b,1)}function bE(a,b){return bG(a,b)}function bD(a,b,c,d,e,f,g,h){if(!(x(a,c)<y(e,g)||y(a,c)>x(e,g)||x(b,d)<y(f,h)||y(b,d)>x(f,h))){var i=(a*d-b*c)*(e-g)-(a-c)*(e*h-f*g),j=(a*d-b*c)*(f-h)-(b-d)*(e*h-f*g),k=(a-c)*(f-h)-(b-d)*(e-g);if(!k)return;var l=i/k,m=j/k,n=+l.toFixed(2),o=+m.toFixed(2);if(n<+y(a,c).toFixed(2)||n>+x(a,c).toFixed(2)||n<+y(e,g).toFixed(2)||n>+x(e,g).toFixed(2)||o<+y(b,d).toFixed(2)||o>+x(b,d).toFixed(2)||o<+y(f,h).toFixed(2)||o>+x(f,h).toFixed(2))return;return{x:l,y:m}}}function bC(a,b,c,d,e,f,g,h,i){if(!(i<0||bB(a,b,c,d,e,f,g,h)<i)){var j=1,k=j/2,l=j-k,m,n=.01;m=bB(a,b,c,d,e,f,g,h,l);while(z(m-i)>n)k/=2,l+=(m<i?1:-1)*k,m=bB(a,b,c,d,e,f,g,h,l);return l}}function bB(a,b,c,d,e,f,g,h,i){i==null&&(i=1),i=i>1?1:i<0?0:i;var j=i/2,k=12,l=[-0.1252,.1252,-0.3678,.3678,-0.5873,.5873,-0.7699,.7699,-0.9041,.9041,-0.9816,.9816],m=[.2491,.2491,.2335,.2335,.2032,.2032,.1601,.1601,.1069,.1069,.0472,.0472],n=0;for(var o=0;o<k;o++){var p=j*l[o]+j,q=bA(p,a,c,e,g),r=bA(p,b,d,f,h),s=q*q+r*r;n+=m[o]*w.sqrt(s)}return j*n}function bA(a,b,c,d,e){var f=-3*b+9*c-9*d+3*e,g=a*f+6*b-12*c+6*d;return a*g-3*b+3*c}function by(a,b){var c=[];for(var d=0,e=a.length;e-2*!b>d;d+=2){var f=[{x:+a[d-2],y:+a[d-1]},{x:+a[d],y:+a[d+1]},{x:+a[d+2],y:+a[d+3]},{x:+a[d+4],y:+a[d+5]}];b?d?e-4==d?f[3]={x:+a[0],y:+a[1]}:e-2==d&&(f[2]={x:+a[0],y:+a[1]},f[3]={x:+a[2],y:+a[3]}):f[0]={x:+a[e-2],y:+a[e-1]}:e-4==d?f[3]=f[2]:d||(f[0]={x:+a[d],y:+a[d+1]}),c.push(["C",(-f[0].x+6*f[1].x+f[2].x)/6,(-f[0].y+6*f[1].y+f[2].y)/6,(f[1].x+6*f[2].x-f[3].x)/6,(f[1].y+6*f[2].y-f[3].y)/6,f[2].x,f[2].y])}return c}function bx(){return this.hex}function bv(a,b,c){function d(){var e=Array.prototype.slice.call(arguments,0),f=e.join("␀"),h=d.cache=d.cache||{},i=d.count=d.count||[];if(h[g](f)){bu(i,f);return c?c(h[f]):h[f]}i.length>=1e3&&delete h[i.shift()],i.push(f),h[f]=a[m](b,e);return c?c(h[f]):h[f]}return d}function bu(a,b){for(var c=0,d=a.length;c<d;c++)if(a[c]===b)return a.push(a.splice(c,1)[0])}function bm(a){if(Object(a)!==a)return a;var b=new a.constructor;for(var c in a)a[g](c)&&(b[c]=bm(a[c]));return b}function a(c){if(a.is(c,"function"))return b?c():eve.on("raphael.DOMload",c);if(a.is(c,E))return a._engine.create[m](a,c.splice(0,3+a.is(c[0],C))).add(c);var d=Array.prototype.slice.call(arguments,0);if(a.is(d[d.length-1],"function")){var e=d.pop();return b?e.call(a._engine.create[m](a,d)):eve.on("raphael.DOMload",function(){e.call(a._engine.create[m](a,d))})}return a._engine.create[m](a,arguments)}a.version="2.1.0",a.eve=eve;var b,c=/[, ]+/,d={circle:1,rect:1,path:1,ellipse:1,text:1,image:1},e=/\{(\d+)\}/g,f="prototype",g="hasOwnProperty",h={doc:document,win:window},i={was:Object.prototype[g].call(h.win,"Raphael"),is:h.win.Raphael},j=function(){this.ca=this.customAttributes={}},k,l="appendChild",m="apply",n="concat",o="createTouch"in h.doc,p="",q=" ",r=String,s="split",t="click dblclick mousedown mousemove mouseout mouseover mouseup touchstart touchmove touchend touchcancel"[s](q),u={mousedown:"touchstart",mousemove:"touchmove",mouseup:"touchend"},v=r.prototype.toLowerCase,w=Math,x=w.max,y=w.min,z=w.abs,A=w.pow,B=w.PI,C="number",D="string",E="array",F="toString",G="fill",H=Object.prototype.toString,I={},J="push",K=a._ISURL=/^url\(['"]?([^\)]+?)['"]?\)$/i,L=/^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgba?\(\s*([\d\.]+%?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+%?(?:\s*,\s*[\d\.]+%?)?)\s*\)|hsba?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\)|hsla?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\))\s*$/i,M={NaN:1,Infinity:1,"-Infinity":1},N=/^(?:cubic-)?bezier\(([^,]+),([^,]+),([^,]+),([^\)]+)\)/,O=w.round,P="setAttribute",Q=parseFloat,R=parseInt,S=r.prototype.toUpperCase,T=a._availableAttrs={"arrow-end":"none","arrow-start":"none",blur:0,"clip-rect":"0 0 1e9 1e9",cursor:"default",cx:0,cy:0,fill:"#fff","fill-opacity":1,font:'10px "Arial"',"font-family":'"Arial"',"font-size":"10","font-style":"normal","font-weight":400,gradient:0,height:0,href:"http://raphaeljs.com/","letter-spacing":0,opacity:1,path:"M0,0",r:0,rx:0,ry:0,src:"",stroke:"#000","stroke-dasharray":"","stroke-linecap":"butt","stroke-linejoin":"butt","stroke-miterlimit":0,"stroke-opacity":1,"stroke-width":1,target:"_blank","text-anchor":"middle",title:"Raphael",transform:"",width:0,x:0,y:0},U=a._availableAnimAttrs={blur:C,"clip-rect":"csv",cx:C,cy:C,fill:"colour","fill-opacity":C,"font-size":C,height:C,opacity:C,path:"path",r:C,rx:C,ry:C,stroke:"colour","stroke-opacity":C,"stroke-width":C,transform:"transform",width:C,x:C,y:C},V=/[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]/g,W=/[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*/,X={hs:1,rg:1},Y=/,?([achlmqrstvxz]),?/gi,Z=/([achlmrqstvz])[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*)+)/ig,$=/([rstm])[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*)+)/ig,_=/(-?\d*\.?\d*(?:e[\-+]?\d+)?)[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*/ig,ba=a._radial_gradient=/^r(?:\(([^,]+?)[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*([^\)]+?)\))?/,bb={},bc=function(a,b){return a.key-b.key},bd=function(a,b){return Q(a)-Q(b)},be=function(){},bf=function(a){return a},bg=a._rectPath=function(a,b,c,d,e){if(e)return[["M",a+e,b],["l",c-e*2,0],["a",e,e,0,0,1,e,e],["l",0,d-e*2],["a",e,e,0,0,1,-e,e],["l",e*2-c,0],["a",e,e,0,0,1,-e,-e],["l",0,e*2-d],["a",e,e,0,0,1,e,-e],["z"]];return[["M",a,b],["l",c,0],["l",0,d],["l",-c,0],["z"]]},bh=function(a,b,c,d){d==null&&(d=c);return[["M",a,b],["m",0,-d],["a",c,d,0,1,1,0,2*d],["a",c,d,0,1,1,0,-2*d],["z"]]},bi=a._getPath={path:function(a){return a.attr("path")},circle:function(a){var b=a.attrs;return bh(b.cx,b.cy,b.r)},ellipse:function(a){var b=a.attrs;return bh(b.cx,b.cy,b.rx,b.ry)},rect:function(a){var b=a.attrs;return bg(b.x,b.y,b.width,b.height,b.r)},image:function(a){var b=a.attrs;return bg(b.x,b.y,b.width,b.height)},text:function(a){var b=a._getBBox();return bg(b.x,b.y,b.width,b.height)}},bj=a.mapPath=function(a,b){if(!b)return a;var c,d,e,f,g,h,i;a=bR(a);for(e=0,g=a.length;e<g;e++){i=a[e];for(f=1,h=i.length;f<h;f+=2)c=b.x(i[f],i[f+1]),d=b.y(i[f],i[f+1]),i[f]=c,i[f+1]=d}return a};a._g=h,a.type=h.win.SVGAngle||h.doc.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1")?"SVG":"VML";if(a.type=="VML"){var bk=h.doc.createElement("div"),bl;bk.innerHTML='<v:shape adj="1"/>',bl=bk.firstChild,bl.style.behavior="url(#default#VML)";if(!bl||typeof bl.adj!="object")return a.type=p;bk=null}a.svg=!(a.vml=a.type=="VML"),a._Paper=j,a.fn=k=j.prototype=a.prototype,a._id=0,a._oid=0,a.is=function(a,b){b=v.call(b);if(b=="finite")return!M[g](+a);if(b=="array")return a instanceof Array;return b=="null"&&a===null||b==typeof a&&a!==null||b=="object"&&a===Object(a)||b=="array"&&Array.isArray&&Array.isArray(a)||H.call(a).slice(8,-1).toLowerCase()==b},a.angle=function(b,c,d,e,f,g){if(f==null){var h=b-d,i=c-e;if(!h&&!i)return 0;return(180+w.atan2(-i,-h)*180/B+360)%360}return a.angle(b,c,f,g)-a.angle(d,e,f,g)},a.rad=function(a){return a%360*B/180},a.deg=function(a){return a*180/B%360},a.snapTo=function(b,c,d){d=a.is(d,"finite")?d:10;if(a.is(b,E)){var e=b.length;while(e--)if(z(b[e]-c)<=d)return b[e]}else{b=+b;var f=c%b;if(f<d)return c-f;if(f>b-d)return c-f+b}return c};var bn=a.createUUID=function(a,b){return function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(a,b).toUpperCase()}}(/[xy]/g,function(a){var b=w.random()*16|0,c=a=="x"?b:b&3|8;return c.toString(16)});a.setWindow=function(b){eve("raphael.setWindow",a,h.win,b),h.win=b,h.doc=h.win.document,a._engine.initWin&&a._engine.initWin(h.win)};var bo=function(b){if(a.vml){var c=/^\s+|\s+$/g,d;try{var e=new ActiveXObject("htmlfile");e.write("<body>"),e.close(),d=e.body}catch(f){d=createPopup().document.body}var g=d.createTextRange();bo=bv(function(a){try{d.style.color=r(a).replace(c,p);var b=g.queryCommandValue("ForeColor");b=(b&255)<<16|b&65280|(b&16711680)>>>16;return"#"+("000000"+b.toString(16)).slice(-6)}catch(e){return"none"}})}else{var i=h.doc.createElement("i");i.title="Raphaël Colour Picker",i.style.display="none",h.doc.body.appendChild(i),bo=bv(function(a){i.style.color=a;return h.doc.defaultView.getComputedStyle(i,p).getPropertyValue("color")})}return bo(b)},bp=function(){return"hsb("+[this.h,this.s,this.b]+")"},bq=function(){return"hsl("+[this.h,this.s,this.l]+")"},br=function(){return this.hex},bs=function(b,c,d){c==null&&a.is(b,"object")&&"r"in b&&"g"in b&&"b"in b&&(d=b.b,c=b.g,b=b.r);if(c==null&&a.is(b,D)){var e=a.getRGB(b);b=e.r,c=e.g,d=e.b}if(b>1||c>1||d>1)b/=255,c/=255,d/=255;return[b,c,d]},bt=function(b,c,d,e){b*=255,c*=255,d*=255;var f={r:b,g:c,b:d,hex:a.rgb(b,c,d),toString:br};a.is(e,"finite")&&(f.opacity=e);return f};a.color=function(b){var c;a.is(b,"object")&&"h"in b&&"s"in b&&"b"in b?(c=a.hsb2rgb(b),b.r=c.r,b.g=c.g,b.b=c.b,b.hex=c.hex):a.is(b,"object")&&"h"in b&&"s"in b&&"l"in b?(c=a.hsl2rgb(b),b.r=c.r,b.g=c.g,b.b=c.b,b.hex=c.hex):(a.is(b,"string")&&(b=a.getRGB(b)),a.is(b,"object")&&"r"in b&&"g"in b&&"b"in b?(c=a.rgb2hsl(b),b.h=c.h,b.s=c.s,b.l=c.l,c=a.rgb2hsb(b),b.v=c.b):(b={hex:"none"},b.r=b.g=b.b=b.h=b.s=b.v=b.l=-1)),b.toString=br;return b},a.hsb2rgb=function(a,b,c,d){this.is(a,"object")&&"h"in a&&"s"in a&&"b"in a&&(c=a.b,b=a.s,a=a.h,d=a.o),a*=360;var e,f,g,h,i;a=a%360/60,i=c*b,h=i*(1-z(a%2-1)),e=f=g=c-i,a=~~a,e+=[i,h,0,0,h,i][a],f+=[h,i,i,h,0,0][a],g+=[0,0,h,i,i,h][a];return bt(e,f,g,d)},a.hsl2rgb=function(a,b,c,d){this.is(a,"object")&&"h"in a&&"s"in a&&"l"in a&&(c=a.l,b=a.s,a=a.h);if(a>1||b>1||c>1)a/=360,b/=100,c/=100;a*=360;var e,f,g,h,i;a=a%360/60,i=2*b*(c<.5?c:1-c),h=i*(1-z(a%2-1)),e=f=g=c-i/2,a=~~a,e+=[i,h,0,0,h,i][a],f+=[h,i,i,h,0,0][a],g+=[0,0,h,i,i,h][a];return bt(e,f,g,d)},a.rgb2hsb=function(a,b,c){c=bs(a,b,c),a=c[0],b=c[1],c=c[2];var d,e,f,g;f=x(a,b,c),g=f-y(a,b,c),d=g==0?null:f==a?(b-c)/g:f==b?(c-a)/g+2:(a-b)/g+4,d=(d+360)%6*60/360,e=g==0?0:g/f;return{h:d,s:e,b:f,toString:bp}},a.rgb2hsl=function(a,b,c){c=bs(a,b,c),a=c[0],b=c[1],c=c[2];var d,e,f,g,h,i;g=x(a,b,c),h=y(a,b,c),i=g-h,d=i==0?null:g==a?(b-c)/i:g==b?(c-a)/i+2:(a-b)/i+4,d=(d+360)%6*60/360,f=(g+h)/2,e=i==0?0:f<.5?i/(2*f):i/(2-2*f);return{h:d,s:e,l:f,toString:bq}},a._path2string=function(){return this.join(",").replace(Y,"$1")};var bw=a._preload=function(a,b){var c=h.doc.createElement("img");c.style.cssText="position:absolute;left:-9999em;top:-9999em",c.onload=function(){b.call(this),this.onload=null,h.doc.body.removeChild(this)},c.onerror=function(){h.doc.body.removeChild(this)},h.doc.body.appendChild(c),c.src=a};a.getRGB=bv(function(b){if(!b||!!((b=r(b)).indexOf("-")+1))return{r:-1,g:-1,b:-1,hex:"none",error:1,toString:bx};if(b=="none")return{r:-1,g:-1,b:-1,hex:"none",toString:bx};!X[g](b.toLowerCase().substring(0,2))&&b.charAt()!="#"&&(b=bo(b));var c,d,e,f,h,i,j,k=b.match(L);if(k){k[2]&&(f=R(k[2].substring(5),16),e=R(k[2].substring(3,5),16),d=R(k[2].substring(1,3),16)),k[3]&&(f=R((i=k[3].charAt(3))+i,16),e=R((i=k[3].charAt(2))+i,16),d=R((i=k[3].charAt(1))+i,16)),k[4]&&(j=k[4][s](W),d=Q(j[0]),j[0].slice(-1)=="%"&&(d*=2.55),e=Q(j[1]),j[1].slice(-1)=="%"&&(e*=2.55),f=Q(j[2]),j[2].slice(-1)=="%"&&(f*=2.55),k[1].toLowerCase().slice(0,4)=="rgba"&&(h=Q(j[3])),j[3]&&j[3].slice(-1)=="%"&&(h/=100));if(k[5]){j=k[5][s](W),d=Q(j[0]),j[0].slice(-1)=="%"&&(d*=2.55),e=Q(j[1]),j[1].slice(-1)=="%"&&(e*=2.55),f=Q(j[2]),j[2].slice(-1)=="%"&&(f*=2.55),(j[0].slice(-3)=="deg"||j[0].slice(-1)=="°")&&(d/=360),k[1].toLowerCase().slice(0,4)=="hsba"&&(h=Q(j[3])),j[3]&&j[3].slice(-1)=="%"&&(h/=100);return a.hsb2rgb(d,e,f,h)}if(k[6]){j=k[6][s](W),d=Q(j[0]),j[0].slice(-1)=="%"&&(d*=2.55),e=Q(j[1]),j[1].slice(-1)=="%"&&(e*=2.55),f=Q(j[2]),j[2].slice(-1)=="%"&&(f*=2.55),(j[0].slice(-3)=="deg"||j[0].slice(-1)=="°")&&(d/=360),k[1].toLowerCase().slice(0,4)=="hsla"&&(h=Q(j[3])),j[3]&&j[3].slice(-1)=="%"&&(h/=100);return a.hsl2rgb(d,e,f,h)}k={r:d,g:e,b:f,toString:bx},k.hex="#"+(16777216|f|e<<8|d<<16).toString(16).slice(1),a.is(h,"finite")&&(k.opacity=h);return k}return{r:-1,g:-1,b:-1,hex:"none",error:1,toString:bx}},a),a.hsb=bv(function(b,c,d){return a.hsb2rgb(b,c,d).hex}),a.hsl=bv(function(b,c,d){return a.hsl2rgb(b,c,d).hex}),a.rgb=bv(function(a,b,c){return"#"+(16777216|c|b<<8|a<<16).toString(16).slice(1)}),a.getColor=function(a){var b=this.getColor.start=this.getColor.start||{h:0,s:1,b:a||.75},c=this.hsb2rgb(b.h,b.s,b.b);b.h+=.075,b.h>1&&(b.h=0,b.s-=.2,b.s<=0&&(this.getColor.start={h:0,s:1,b:b.b}));return c.hex},a.getColor.reset=function(){delete this.start},a.parsePathString=function(b){if(!b)return null;var c=bz(b);if(c.arr)return bJ(c.arr);var d={a:7,c:6,h:1,l:2,m:2,r:4,q:4,s:4,t:2,v:1,z:0},e=[];a.is(b,E)&&a.is(b[0],E)&&(e=bJ(b)),e.length||r(b).replace(Z,function(a,b,c){var f=[],g=b.toLowerCase();c.replace(_,function(a,b){b&&f.push(+b)}),g=="m"&&f.length>2&&(e.push([b][n](f.splice(0,2))),g="l",b=b=="m"?"l":"L");if(g=="r")e.push([b][n](f));else while(f.length>=d[g]){e.push([b][n](f.splice(0,d[g])));if(!d[g])break}}),e.toString=a._path2string,c.arr=bJ(e);return e},a.parseTransformString=bv(function(b){if(!b)return null;var c={r:3,s:4,t:2,m:6},d=[];a.is(b,E)&&a.is(b[0],E)&&(d=bJ(b)),d.length||r(b).replace($,function(a,b,c){var e=[],f=v.call(b);c.replace(_,function(a,b){b&&e.push(+b)}),d.push([b][n](e))}),d.toString=a._path2string;return d});var bz=function(a){var b=bz.ps=bz.ps||{};b[a]?b[a].sleep=100:b[a]={sleep:100},setTimeout(function(){for(var c in b)b[g](c)&&c!=a&&(b[c].sleep--,!b[c].sleep&&delete b[c])});return b[a]};a.findDotsAtSegment=function(a,b,c,d,e,f,g,h,i){var j=1-i,k=A(j,3),l=A(j,2),m=i*i,n=m*i,o=k*a+l*3*i*c+j*3*i*i*e+n*g,p=k*b+l*3*i*d+j*3*i*i*f+n*h,q=a+2*i*(c-a)+m*(e-2*c+a),r=b+2*i*(d-b)+m*(f-2*d+b),s=c+2*i*(e-c)+m*(g-2*e+c),t=d+2*i*(f-d)+m*(h-2*f+d),u=j*a+i*c,v=j*b+i*d,x=j*e+i*g,y=j*f+i*h,z=90-w.atan2(q-s,r-t)*180/B;(q>s||r<t)&&(z+=180);return{x:o,y:p,m:{x:q,y:r},n:{x:s,y:t},start:{x:u,y:v},end:{x:x,y:y},alpha:z}},a.bezierBBox=function(b,c,d,e,f,g,h,i){a.is(b,"array")||(b=[b,c,d,e,f,g,h,i]);var j=bQ.apply(null,b);return{x:j.min.x,y:j.min.y,x2:j.max.x,y2:j.max.y,width:j.max.x-j.min.x,height:j.max.y-j.min.y}},a.isPointInsideBBox=function(a,b,c){return b>=a.x&&b<=a.x2&&c>=a.y&&c<=a.y2},a.isBBoxIntersect=function(b,c){var d=a.isPointInsideBBox;return d(c,b.x,b.y)||d(c,b.x2,b.y)||d(c,b.x,b.y2)||d(c,b.x2,b.y2)||d(b,c.x,c.y)||d(b,c.x2,c.y)||d(b,c.x,c.y2)||d(b,c.x2,c.y2)||(b.x<c.x2&&b.x>c.x||c.x<b.x2&&c.x>b.x)&&(b.y<c.y2&&b.y>c.y||c.y<b.y2&&c.y>b.y)},a.pathIntersection=function(a,b){return bH(a,b)},a.pathIntersectionNumber=function(a,b){return bH(a,b,1)},a.isPointInsidePath=function(b,c,d){var e=a.pathBBox(b);return a.isPointInsideBBox(e,c,d)&&bH(b,[["M",c,d],["H",e.x2+10]],1)%2==1},a._removedFactory=function(a){return function(){eve("raphael.log",null,"Raphaël: you are calling to method “"+a+"” of removed object",a)}};var bI=a.pathBBox=function(a){var b=bz(a);if(b.bbox)return b.bbox;if(!a)return{x:0,y:0,width:0,height:0,x2:0,y2:0};a=bR(a);var c=0,d=0,e=[],f=[],g;for(var h=0,i=a.length;h<i;h++){g=a[h];if(g[0]=="M")c=g[1],d=g[2],e.push(c),f.push(d);else{var j=bQ(c,d,g[1],g[2],g[3],g[4],g[5],g[6]);e=e[n](j.min.x,j.max.x),f=f[n](j.min.y,j.max.y),c=g[5],d=g[6]}}var k=y[m](0,e),l=y[m](0,f),o=x[m](0,e),p=x[m](0,f),q={x:k,y:l,x2:o,y2:p,width:o-k,height:p-l};b.bbox=bm(q);return q},bJ=function(b){var c=bm(b);c.toString=a._path2string;return c},bK=a._pathToRelative=function(b){var c=bz(b);if(c.rel)return bJ(c.rel);if(!a.is(b,E)||!a.is(b&&b[0],E))b=a.parsePathString(b);var d=[],e=0,f=0,g=0,h=0,i=0;b[0][0]=="M"&&(e=b[0][1],f=b[0][2],g=e,h=f,i++,d.push(["M",e,f]));for(var j=i,k=b.length;j<k;j++){var l=d[j]=[],m=b[j];if(m[0]!=v.call(m[0])){l[0]=v.call(m[0]);switch(l[0]){case"a":l[1]=m[1],l[2]=m[2],l[3]=m[3],l[4]=m[4],l[5]=m[5],l[6]=+(m[6]-e).toFixed(3),l[7]=+(m[7]-f).toFixed(3);break;case"v":l[1]=+(m[1]-f).toFixed(3);break;case"m":g=m[1],h=m[2];default:for(var n=1,o=m.length;n<o;n++)l[n]=+(m[n]-(n%2?e:f)).toFixed(3)}}else{l=d[j]=[],m[0]=="m"&&(g=m[1]+e,h=m[2]+f);for(var p=0,q=m.length;p<q;p++)d[j][p]=m[p]}var r=d[j].length;switch(d[j][0]){case"z":e=g,f=h;break;case"h":e+=+d[j][r-1];break;case"v":f+=+d[j][r-1];break;default:e+=+d[j][r-2],f+=+d[j][r-1]}}d.toString=a._path2string,c.rel=bJ(d);return d},bL=a._pathToAbsolute=function(b){var c=bz(b);if(c.abs)return bJ(c.abs);if(!a.is(b,E)||!a.is(b&&b[0],E))b=a.parsePathString(b);if(!b||!b.length)return[["M",0,0]];var d=[],e=0,f=0,g=0,h=0,i=0;b[0][0]=="M"&&(e=+b[0][1],f=+b[0][2],g=e,h=f,i++,d[0]=["M",e,f]);var j=b.length==3&&b[0][0]=="M"&&b[1][0].toUpperCase()=="R"&&b[2][0].toUpperCase()=="Z";for(var k,l,m=i,o=b.length;m<o;m++){d.push(k=[]),l=b[m];if(l[0]!=S.call(l[0])){k[0]=S.call(l[0]);switch(k[0]){case"A":k[1]=l[1],k[2]=l[2],k[3]=l[3],k[4]=l[4],k[5]=l[5],k[6]=+(l[6]+e),k[7]=+(l[7]+f);break;case"V":k[1]=+l[1]+f;break;case"H":k[1]=+l[1]+e;break;case"R":var p=[e,f][n](l.slice(1));for(var q=2,r=p.length;q<r;q++)p[q]=+p[q]+e,p[++q]=+p[q]+f;d.pop(),d=d[n](by(p,j));break;case"M":g=+l[1]+e,h=+l[2]+f;default:for(q=1,r=l.length;q<r;q++)k[q]=+l[q]+(q%2?e:f)}}else if(l[0]=="R")p=[e,f][n](l.slice(1)),d.pop(),d=d[n](by(p,j)),k=["R"][n](l.slice(-2));else for(var s=0,t=l.length;s<t;s++)k[s]=l[s];switch(k[0]){case"Z":e=g,f=h;break;case"H":e=k[1];break;case"V":f=k[1];break;case"M":g=k[k.length-2],h=k[k.length-1];default:e=k[k.length-2],f=k[k.length-1]}}d.toString=a._path2string,c.abs=bJ(d);return d},bM=function(a,b,c,d){return[a,b,c,d,c,d]},bN=function(a,b,c,d,e,f){var g=1/3,h=2/3;return[g*a+h*c,g*b+h*d,g*e+h*c,g*f+h*d,e,f]},bO=function(a,b,c,d,e,f,g,h,i,j){var k=B*120/180,l=B/180*(+e||0),m=[],o,p=bv(function(a,b,c){var d=a*w.cos(c)-b*w.sin(c),e=a*w.sin(c)+b*w.cos(c);return{x:d,y:e}});if(!j){o=p(a,b,-l),a=o.x,b=o.y,o=p(h,i,-l),h=o.x,i=o.y;var q=w.cos(B/180*e),r=w.sin(B/180*e),t=(a-h)/2,u=(b-i)/2,v=t*t/(c*c)+u*u/(d*d);v>1&&(v=w.sqrt(v),c=v*c,d=v*d);var x=c*c,y=d*d,A=(f==g?-1:1)*w.sqrt(z((x*y-x*u*u-y*t*t)/(x*u*u+y*t*t))),C=A*c*u/d+(a+h)/2,D=A*-d*t/c+(b+i)/2,E=w.asin(((b-D)/d).toFixed(9)),F=w.asin(((i-D)/d).toFixed(9));E=a<C?B-E:E,F=h<C?B-F:F,E<0&&(E=B*2+E),F<0&&(F=B*2+F),g&&E>F&&(E=E-B*2),!g&&F>E&&(F=F-B*2)}else E=j[0],F=j[1],C=j[2],D=j[3];var G=F-E;if(z(G)>k){var H=F,I=h,J=i;F=E+k*(g&&F>E?1:-1),h=C+c*w.cos(F),i=D+d*w.sin(F),m=bO(h,i,c,d,e,0,g,I,J,[F,H,C,D])}G=F-E;var K=w.cos(E),L=w.sin(E),M=w.cos(F),N=w.sin(F),O=w.tan(G/4),P=4/3*c*O,Q=4/3*d*O,R=[a,b],S=[a+P*L,b-Q*K],T=[h+P*N,i-Q*M],U=[h,i];S[0]=2*R[0]-S[0],S[1]=2*R[1]-S[1];if(j)return[S,T,U][n](m);m=[S,T,U][n](m).join()[s](",");var V=[];for(var W=0,X=m.length;W<X;W++)V[W]=W%2?p(m[W-1],m[W],l).y:p(m[W],m[W+1],l).x;return V},bP=function(a,b,c,d,e,f,g,h,i){var j=1-i;return{x:A(j,3)*a+A(j,2)*3*i*c+j*3*i*i*e+A(i,3)*g,y:A(j,3)*b+A(j,2)*3*i*d+j*3*i*i*f+A(i,3)*h}},bQ=bv(function(a,b,c,d,e,f,g,h){var i=e-2*c+a-(g-2*e+c),j=2*(c-a)-2*(e-c),k=a-c,l=(-j+w.sqrt(j*j-4*i*k))/2/i,n=(-j-w.sqrt(j*j-4*i*k))/2/i,o=[b,h],p=[a,g],q;z(l)>"1e12"&&(l=.5),z(n)>"1e12"&&(n=.5),l>0&&l<1&&(q=bP(a,b,c,d,e,f,g,h,l),p.push(q.x),o.push(q.y)),n>0&&n<1&&(q=bP(a,b,c,d,e,f,g,h,n),p.push(q.x),o.push(q.y)),i=f-2*d+b-(h-2*f+d),j=2*(d-b)-2*(f-d),k=b-d,l=(-j+w.sqrt(j*j-4*i*k))/2/i,n=(-j-w.sqrt(j*j-4*i*k))/2/i,z(l)>"1e12"&&(l=.5),z(n)>"1e12"&&(n=.5),l>0&&l<1&&(q=bP(a,b,c,d,e,f,g,h,l),p.push(q.x),o.push(q.y)),n>0&&n<1&&(q=bP(a,b,c,d,e,f,g,h,n),p.push(q.x),o.push(q.y));return{min:{x:y[m](0,p),y:y[m](0,o)},max:{x:x[m](0,p),y:x[m](0,o)}}}),bR=a._path2curve=bv(function(a,b){var c=!b&&bz(a);if(!b&&c.curve)return bJ(c.curve);var d=bL(a),e=b&&bL(b),f={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},g={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},h=function(a,b){var c,d;if(!a)return["C",b.x,b.y,b.x,b.y,b.x,b.y];!(a[0]in{T:1,Q:1})&&(b.qx=b.qy=null);switch(a[0]){case"M":b.X=a[1],b.Y=a[2];break;case"A":a=["C"][n](bO[m](0,[b.x,b.y][n](a.slice(1))));break;case"S":c=b.x+(b.x-(b.bx||b.x)),d=b.y+(b.y-(b.by||b.y)),a=["C",c,d][n](a.slice(1));break;case"T":b.qx=b.x+(b.x-(b.qx||b.x)),b.qy=b.y+(b.y-(b.qy||b.y)),a=["C"][n](bN(b.x,b.y,b.qx,b.qy,a[1],a[2]));break;case"Q":b.qx=a[1],b.qy=a[2],a=["C"][n](bN(b.x,b.y,a[1],a[2],a[3],a[4]));break;case"L":a=["C"][n](bM(b.x,b.y,a[1],a[2]));break;case"H":a=["C"][n](bM(b.x,b.y,a[1],b.y));break;case"V":a=["C"][n](bM(b.x,b.y,b.x,a[1]));break;case"Z":a=["C"][n](bM(b.x,b.y,b.X,b.Y))}return a},i=function(a,b){if(a[b].length>7){a[b].shift();var c=a[b];while(c.length)a.splice(b++,0,["C"][n](c.splice(0,6)));a.splice(b,1),l=x(d.length,e&&e.length||0)}},j=function(a,b,c,f,g){a&&b&&a[g][0]=="M"&&b[g][0]!="M"&&(b.splice(g,0,["M",f.x,f.y]),c.bx=0,c.by=0,c.x=a[g][1],c.y=a[g][2],l=x(d.length,e&&e.length||0))};for(var k=0,l=x(d.length,e&&e.length||0);k<l;k++){d[k]=h(d[k],f),i(d,k),e&&(e[k]=h(e[k],g)),e&&i(e,k),j(d,e,f,g,k),j(e,d,g,f,k);var o=d[k],p=e&&e[k],q=o.length,r=e&&p.length;f.x=o[q-2],f.y=o[q-1],f.bx=Q(o[q-4])||f.x,f.by=Q(o[q-3])||f.y,g.bx=e&&(Q(p[r-4])||g.x),g.by=e&&(Q(p[r-3])||g.y),g.x=e&&p[r-2],g.y=e&&p[r-1]}e||(c.curve=bJ(d));return e?[d,e]:d},null,bJ),bS=a._parseDots=bv(function(b){var c=[];for(var d=0,e=b.length;d<e;d++){var f={},g=b[d].match(/^([^:]*):?([\d\.]*)/);f.color=a.getRGB(g[1]);if(f.color.error)return null;f.color=f.color.hex,g[2]&&(f.offset=g[2]+"%"),c.push(f)}for(d=1,e=c.length-1;d<e;d++)if(!c[d].offset){var h=Q(c[d-1].offset||0),i=0;for(var j=d+1;j<e;j++)if(c[j].offset){i=c[j].offset;break}i||(i=100,j=e),i=Q(i);var k=(i-h)/(j-d+1);for(;d<j;d++)h+=k,c[d].offset=h+"%"}return c}),bT=a._tear=function(a,b){a==b.top&&(b.top=a.prev),a==b.bottom&&(b.bottom=a.next),a.next&&(a.next.prev=a.prev),a.prev&&(a.prev.next=a.next)},bU=a._tofront=function(a,b){b.top!==a&&(bT(a,b),a.next=null,a.prev=b.top,b.top.next=a,b.top=a)},bV=a._toback=function(a,b){b.bottom!==a&&(bT(a,b),a.next=b.bottom,a.prev=null,b.bottom.prev=a,b.bottom=a)},bW=a._insertafter=function(a,b,c){bT(a,c),b==c.top&&(c.top=a),b.next&&(b.next.prev=a),a.next=b.next,a.prev=b,b.next=a},bX=a._insertbefore=function(a,b,c){bT(a,c),b==c.bottom&&(c.bottom=a),b.prev&&(b.prev.next=a),a.prev=b.prev,b.prev=a,a.next=b},bY=a.toMatrix=function(a,b){var c=bI(a),d={_:{transform:p},getBBox:function(){return c}};b$(d,b);return d.matrix},bZ=a.transformPath=function(a,b){return bj(a,bY(a,b))},b$=a._extractTransform=function(b,c){if(c==null)return b._.transform;c=r(c).replace(/\.{3}|\u2026/g,b._.transform||p);var d=a.parseTransformString(c),e=0,f=0,g=0,h=1,i=1,j=b._,k=new cb;j.transform=d||[];if(d)for(var l=0,m=d.length;l<m;l++){var n=d[l],o=n.length,q=r(n[0]).toLowerCase(),s=n[0]!=q,t=s?k.invert():0,u,v,w,x,y;q=="t"&&o==3?s?(u=t.x(0,0),v=t.y(0,0),w=t.x(n[1],n[2]),x=t.y(n[1],n[2]),k.translate(w-u,x-v)):k.translate(n[1],n[2]):q=="r"?o==2?(y=y||b.getBBox(1),k.rotate(n[1],y.x+y.width/2,y.y+y.height/2),e+=n[1]):o==4&&(s?(w=t.x(n[2],n[3]),x=t.y(n[2],n[3]),k.rotate(n[1],w,x)):k.rotate(n[1],n[2],n[3]),e+=n[1]):q=="s"?o==2||o==3?(y=y||b.getBBox(1),k.scale(n[1],n[o-1],y.x+y.width/2,y.y+y.height/2),h*=n[1],i*=n[o-1]):o==5&&(s?(w=t.x(n[3],n[4]),x=t.y(n[3],n[4]),k.scale(n[1],n[2],w,x)):k.scale(n[1],n[2],n[3],n[4]),h*=n[1],i*=n[2]):q=="m"&&o==7&&k.add(n[1],n[2],n[3],n[4],n[5],n[6]),j.dirtyT=1,b.matrix=k}b.matrix=k,j.sx=h,j.sy=i,j.deg=e,j.dx=f=k.e,j.dy=g=k.f,h==1&&i==1&&!e&&j.bbox?(j.bbox.x+=+f,j.bbox.y+=+g):j.dirtyT=1},b_=function(a){var b=a[0];switch(b.toLowerCase()){case"t":return[b,0,0];case"m":return[b,1,0,0,1,0,0];case"r":return a.length==4?[b,0,a[2],a[3]]:[b,0];case"s":return a.length==5?[b,1,1,a[3],a[4]]:a.length==3?[b,1,1]:[b,1]}},ca=a._equaliseTransform=function(b,c){c=r(c).replace(/\.{3}|\u2026/g,b),b=a.parseTransformString(b)||[],c=a.parseTransformString(c)||[];var d=x(b.length,c.length),e=[],f=[],g=0,h,i,j,k;for(;g<d;g++){j=b[g]||b_(c[g]),k=c[g]||b_(j);if(j[0]!=k[0]||j[0].toLowerCase()=="r"&&(j[2]!=k[2]||j[3]!=k[3])||j[0].toLowerCase()=="s"&&(j[3]!=k[3]||j[4]!=k[4]))return;e[g]=[],f[g]=[];for(h=0,i=x(j.length,k.length);h<i;h++)h in j&&(e[g][h]=j[h]),h in k&&(f[g][h]=k[h])}return{from:e,to:f}};a._getContainer=function(b,c,d,e){var f;f=e==null&&!a.is(b,"object")?h.doc.getElementById(b):b;if(f!=null){if(f.tagName)return c==null?{container:f,width:f.style.pixelWidth||f.offsetWidth,height:f.style.pixelHeight||f.offsetHeight}:{container:f,width:c,height:d};return{container:1,x:b,y:c,width:d,height:e}}},a.pathToRelative=bK,a._engine={},a.path2curve=bR,a.matrix=function(a,b,c,d,e,f){return new cb(a,b,c,d,e,f)},function(b){function d(a){var b=w.sqrt(c(a));a[0]&&(a[0]/=b),a[1]&&(a[1]/=b)}function c(a){return a[0]*a[0]+a[1]*a[1]}b.add=function(a,b,c,d,e,f){var g=[[],[],[]],h=[[this.a,this.c,this.e],[this.b,this.d,this.f],[0,0,1]],i=[[a,c,e],[b,d,f],[0,0,1]],j,k,l,m;a&&a instanceof cb&&(i=[[a.a,a.c,a.e],[a.b,a.d,a.f],[0,0,1]]);for(j=0;j<3;j++)for(k=0;k<3;k++){m=0;for(l=0;l<3;l++)m+=h[j][l]*i[l][k];g[j][k]=m}this.a=g[0][0],this.b=g[1][0],this.c=g[0][1],this.d=g[1][1],this.e=g[0][2],this.f=g[1][2]},b.invert=function(){var a=this,b=a.a*a.d-a.b*a.c;return new cb(a.d/b,-a.b/b,-a.c/b,a.a/b,(a.c*a.f-a.d*a.e)/b,(a.b*a.e-a.a*a.f)/b)},b.clone=function(){return new cb(this.a,this.b,this.c,this.d,this.e,this.f)},b.translate=function(a,b){this.add(1,0,0,1,a,b)},b.scale=function(a,b,c,d){b==null&&(b=a),(c||d)&&this.add(1,0,0,1,c,d),this.add(a,0,0,b,0,0),(c||d)&&this.add(1,0,0,1,-c,-d)},b.rotate=function(b,c,d){b=a.rad(b),c=c||0,d=d||0;var e=+w.cos(b).toFixed(9),f=+w.sin(b).toFixed(9);this.add(e,f,-f,e,c,d),this.add(1,0,0,1,-c,-d)},b.x=function(a,b){return a*this.a+b*this.c+this.e},b.y=function(a,b){return a*this.b+b*this.d+this.f},b.get=function(a){return+this[r.fromCharCode(97+a)].toFixed(4)},b.toString=function(){return a.svg?"matrix("+[this.get(0),this.get(1),this.get(2),this.get(3),this.get(4),this.get(5)].join()+")":[this.get(0),this.get(2),this.get(1),this.get(3),0,0].join()},b.toFilter=function(){return"progid:DXImageTransform.Microsoft.Matrix(M11="+this.get(0)+", M12="+this.get(2)+", M21="+this.get(1)+", M22="+this.get(3)+", Dx="+this.get(4)+", Dy="+this.get(5)+", sizingmethod='auto expand')"},b.offset=function(){return[this.e.toFixed(4),this.f.toFixed(4)]},b.split=function(){var b={};b.dx=this.e,b.dy=this.f;var e=[[this.a,this.c],[this.b,this.d]];b.scalex=w.sqrt(c(e[0])),d(e[0]),b.shear=e[0][0]*e[1][0]+e[0][1]*e[1][1],e[1]=[e[1][0]-e[0][0]*b.shear,e[1][1]-e[0][1]*b.shear],b.scaley=w.sqrt(c(e[1])),d(e[1]),b.shear/=b.scaley;var f=-e[0][1],g=e[1][1];g<0?(b.rotate=a.deg(w.acos(g)),f<0&&(b.rotate=360-b.rotate)):b.rotate=a.deg(w.asin(f)),b.isSimple=!+b.shear.toFixed(9)&&(b.scalex.toFixed(9)==b.scaley.toFixed(9)||!b.rotate),b.isSuperSimple=!+b.shear.toFixed(9)&&b.scalex.toFixed(9)==b.scaley.toFixed(9)&&!b.rotate,b.noRotation=!+b.shear.toFixed(9)&&!b.rotate;return b},b.toTransformString=function(a){var b=a||this[s]();if(b.isSimple){b.scalex=+b.scalex.toFixed(4),b.scaley=+b.scaley.toFixed(4),b.rotate=+b.rotate.toFixed(4);return(b.dx||b.dy?"t"+[b.dx,b.dy]:p)+(b.scalex!=1||b.scaley!=1?"s"+[b.scalex,b.scaley,0,0]:p)+(b.rotate?"r"+[b.rotate,0,0]:p)}return"m"+[this.get(0),this.get(1),this.get(2),this.get(3),this.get(4),this.get(5)]}}(cb.prototype);var cc=navigator.userAgent.match(/Version\/(.*?)\s/)||navigator.userAgent.match(/Chrome\/(\d+)/);navigator.vendor=="Apple Computer, Inc."&&(cc&&cc[1]<4||navigator.platform.slice(0,2)=="iP")||navigator.vendor=="Google Inc."&&cc&&cc[1]<8?k.safari=function(){var a=this.rect(-99,-99,this.width+99,this.height+99).attr({stroke:"none"});setTimeout(function(){a.remove()})}:k.safari=be;var cd=function(){this.returnValue=!1},ce=function(){return this.originalEvent.preventDefault()},cf=function(){this.cancelBubble=!0},cg=function(){return this.originalEvent.stopPropagation()},ch=function(){if(h.doc.addEventListener)return function(a,b,c,d){var e=o&&u[b]?u[b]:b,f=function(e){var f=h.doc.documentElement.scrollTop||h.doc.body.scrollTop,i=h.doc.documentElement.scrollLeft||h.doc.body.scrollLeft,j=e.clientX+i,k=e.clientY+f;if(o&&u[g](b))for(var l=0,m=e.targetTouches&&e.targetTouches.length;l<m;l++)if(e.targetTouches[l].target==a){var n=e;e=e.targetTouches[l],e.originalEvent=n,e.preventDefault=ce,e.stopPropagation=cg;break}return c.call(d,e,j,k)};a.addEventListener(e,f,!1);return function(){a.removeEventListener(e,f,!1);return!0}};if(h.doc.attachEvent)return function(a,b,c,d){var e=function(a){a=a||h.win.event;var b=h.doc.documentElement.scrollTop||h.doc.body.scrollTop,e=h.doc.documentElement.scrollLeft||h.doc.body.scrollLeft,f=a.clientX+e,g=a.clientY+b;a.preventDefault=a.preventDefault||cd,a.stopPropagation=a.stopPropagation||cf;return c.call(d,a,f,g)};a.attachEvent("on"+b,e);var f=function(){a.detachEvent("on"+b,e);return!0};return f}}(),ci=[],cj=function(a){var b=a.clientX,c=a.clientY,d=h.doc.documentElement.scrollTop||h.doc.body.scrollTop,e=h.doc.documentElement.scrollLeft||h.doc.body.scrollLeft,f,g=ci.length;while(g--){f=ci[g];if(o){var i=a.touches.length,j;while(i--){j=a.touches[i];if(j.identifier==f.el._drag.id){b=j.clientX,c=j.clientY,(a.originalEvent?a.originalEvent:a).preventDefault();break}}}else a.preventDefault();var k=f.el.node,l,m=k.nextSibling,n=k.parentNode,p=k.style.display;h.win.opera&&n.removeChild(k),k.style.display="none",l=f.el.paper.getElementByPoint(b,c),k.style.display=p,h.win.opera&&(m?n.insertBefore(k,m):n.appendChild(k)),l&&eve("raphael.drag.over."+f.el.id,f.el,l),b+=e,c+=d,eve("raphael.drag.move."+f.el.id,f.move_scope||f.el,b-f.el._drag.x,c-f.el._drag.y,b,c,a)}},ck=function(b){a.unmousemove(cj).unmouseup(ck);var c=ci.length,d;while(c--)d=ci[c],d.el._drag={},eve("raphael.drag.end."+d.el.id,d.end_scope||d.start_scope||d.move_scope||d.el,b);ci=[]},cl=a.el={};for(var cm=t.length;cm--;)(function(b){a[b]=cl[b]=function(c,d){a.is(c,"function")&&(this.events=this.events||[],this.events.push({name:b,f:c,unbind:ch(this.shape||this.node||h.doc,b,c,d||this)}));return this},a["un"+b]=cl["un"+b]=function(a){var c=this.events||[],d=c.length;while(d--)if(c[d].name==b&&c[d].f==a){c[d].unbind(),c.splice(d,1),!c.length&&delete this.events;return this}return this}})(t[cm]);cl.data=function(b,c){var d=bb[this.id]=bb[this.id]||{};if(arguments.length==1){if(a.is(b,"object")){for(var e in b)b[g](e)&&this.data(e,b[e]);return this}eve("raphael.data.get."+this.id,this,d[b],b);return d[b]}d[b]=c,eve("raphael.data.set."+this.id,this,c,b);return this},cl.removeData=function(a){a==null?bb[this.id]={}:bb[this.id]&&delete bb[this.id][a];return this},cl.hover=function(a,b,c,d){return this.mouseover(a,c).mouseout(b,d||c)},cl.unhover=function(a,b){return this.unmouseover(a).unmouseout(b)};var cn=[];cl.drag=function(b,c,d,e,f,g){function i(i){(i.originalEvent||i).preventDefault();var j=h.doc.documentElement.scrollTop||h.doc.body.scrollTop,k=h.doc.documentElement.scrollLeft||h.doc.body.scrollLeft;this._drag.x=i.clientX+k,this._drag.y=i.clientY+j,this._drag.id=i.identifier,!ci.length&&a.mousemove(cj).mouseup(ck),ci.push({el:this,move_scope:e,start_scope:f,end_scope:g}),c&&eve.on("raphael.drag.start."+this.id,c),b&&eve.on("raphael.drag.move."+this.id,b),d&&eve.on("raphael.drag.end."+this.id,d),eve("raphael.drag.start."+this.id,f||e||this,i.clientX+k,i.clientY+j,i)}this._drag={},cn.push({el:this,start:i}),this.mousedown(i);return this},cl.onDragOver=function(a){a?eve.on("raphael.drag.over."+this.id,a):eve.unbind("raphael.drag.over."+this.id)},cl.undrag=function(){var b=cn.length;while(b--)cn[b].el==this&&(this.unmousedown(cn[b].start),cn.splice(b,1),eve.unbind("raphael.drag.*."+this.id));!cn.length&&a.unmousemove(cj).unmouseup(ck)},k.circle=function(b,c,d){var e=a._engine.circle(this,b||0,c||0,d||0);this.__set__&&this.__set__.push(e);return e},k.rect=function(b,c,d,e,f){var g=a._engine.rect(this,b||0,c||0,d||0,e||0,f||0);this.__set__&&this.__set__.push(g);return g},k.ellipse=function(b,c,d,e){var f=a._engine.ellipse(this,b||0,c||0,d||0,e||0);this.__set__&&this.__set__.push(f);return f},k.path=function(b){b&&!a.is(b,D)&&!a.is(b[0],E)&&(b+=p);var c=a._engine.path(a.format[m](a,arguments),this);this.__set__&&this.__set__.push(c);return c},k.image=function(b,c,d,e,f){var g=a._engine.image(this,b||"about:blank",c||0,d||0,e||0,f||0);this.__set__&&this.__set__.push(g);return g},k.text=function(b,c,d){var e=a._engine.text(this,b||0,c||0,r(d));this.__set__&&this.__set__.push(e);return e},k.set=function(b){!a.is(b,"array")&&(b=Array.prototype.splice.call(arguments,0,arguments.length));var c=new cG(b);this.__set__&&this.__set__.push(c);return c},k.setStart=function(a){this.__set__=a||this.set()},k.setFinish=function(a){var b=this.__set__;delete this.__set__;return b},k.setSize=function(b,c){return a._engine.setSize.call(this,b,c)},k.setViewBox=function(b,c,d,e,f){return a._engine.setViewBox.call(this,b,c,d,e,f)},k.top=k.bottom=null,k.raphael=a;var co=function(a){var b=a.getBoundingClientRect(),c=a.ownerDocument,d=c.body,e=c.documentElement,f=e.clientTop||d.clientTop||0,g=e.clientLeft||d.clientLeft||0,i=b.top+(h.win.pageYOffset||e.scrollTop||d.scrollTop)-f,j=b.left+(h.win.pageXOffset||e.scrollLeft||d.scrollLeft)-g;return{y:i,x:j}};k.getElementByPoint=function(a,b){var c=this,d=c.canvas,e=h.doc.elementFromPoint(a,b);if(h.win.opera&&e.tagName=="svg"){var f=co(d),g=d.createSVGRect();g.x=a-f.x,g.y=b-f.y,g.width=g.height=1;var i=d.getIntersectionList(g,null);i.length&&(e=i[i.length-1])}if(!e)return null;while(e.parentNode&&e!=d.parentNode&&!e.raphael)e=e.parentNode;e==c.canvas.parentNode&&(e=d),e=e&&e.raphael?c.getById(e.raphaelid):null;return e},k.getById=function(a){var b=this.bottom;while(b){if(b.id==a)return b;b=b.next}return null},k.forEach=function(a,b){var c=this.bottom;while(c){if(a.call(b,c)===!1)return this;c=c.next}return this},k.getElementsByPoint=function(a,b){var c=this.set();this.forEach(function(d){d.isPointInside(a,b)&&c.push(d)});return c},cl.isPointInside=function(b,c){var d=this.realPath=this.realPath||bi[this.type](this);return a.isPointInsidePath(d,b,c)},cl.getBBox=function(a){if(this.removed)return{};var b=this._;if(a){if(b.dirty||!b.bboxwt)this.realPath=bi[this.type](this),b.bboxwt=bI(this.realPath),b.bboxwt.toString=cq,b.dirty=0;return b.bboxwt}if(b.dirty||b.dirtyT||!b.bbox){if(b.dirty||!this.realPath)b.bboxwt=0,this.realPath=bi[this.type](this);b.bbox=bI(bj(this.realPath,this.matrix)),b.bbox.toString=cq,b.dirty=b.dirtyT=0}return b.bbox},cl.clone=function(){if(this.removed)return null;var a=this.paper[this.type]().attr(this.attr());this.__set__&&this.__set__.push(a);return a},cl.glow=function(a){if(this.type=="text")return null;a=a||{};var b={width:(a.width||10)+(+this.attr("stroke-width")||1),fill:a.fill||!1,opacity:a.opacity||.5,offsetx:a.offsetx||0,offsety:a.offsety||0,color:a.color||"#000"},c=b.width/2,d=this.paper,e=d.set(),f=this.realPath||bi[this.type](this);f=this.matrix?bj(f,this.matrix):f;for(var g=1;g<c+1;g++)e.push(d.path(f).attr({stroke:b.color,fill:b.fill?b.color:"none","stroke-linejoin":"round","stroke-linecap":"round","stroke-width":+(b.width/c*g).toFixed(3),opacity:+(b.opacity/c).toFixed(3)}));return e.insertBefore(this).translate(b.offsetx,b.offsety)};var cr={},cs=function(b,c,d,e,f,g,h,i,j){return j==null?bB(b,c,d,e,f,g,h,i):a.findDotsAtSegment(b,c,d,e,f,g,h,i,bC(b,c,d,e,f,g,h,i,j))},ct=function(b,c){return function(d,e,f){d=bR(d);var g,h,i,j,k="",l={},m,n=0;for(var o=0,p=d.length;o<p;o++){i=d[o];if(i[0]=="M")g=+i[1],h=+i[2];else{j=cs(g,h,i[1],i[2],i[3],i[4],i[5],i[6]);if(n+j>e){if(c&&!l.start){m=cs(g,h,i[1],i[2],i[3],i[4],i[5],i[6],e-n),k+=["C"+m.start.x,m.start.y,m.m.x,m.m.y,m.x,m.y];if(f)return k;l.start=k,k=["M"+m.x,m.y+"C"+m.n.x,m.n.y,m.end.x,m.end.y,i[5],i[6]].join(),n+=j,g=+i[5],h=+i[6];continue}if(!b&&!c){m=cs(g,h,i[1],i[2],i[3],i[4],i[5],i[6],e-n);return{x:m.x,y:m.y,alpha:m.alpha}}}n+=j,g=+i[5],h=+i[6]}k+=i.shift()+i}l.end=k,m=b?n:c?l:a.findDotsAtSegment(g,h,i[0],i[1],i[2],i[3],i[4],i[5],1),m.alpha&&(m={x:m.x,y:m.y,alpha:m.alpha});return m}},cu=ct(1),cv=ct(),cw=ct(0,1);a.getTotalLength=cu,a.getPointAtLength=cv,a.getSubpath=function(a,b,c){if(this.getTotalLength(a)-c<1e-6)return cw(a,b).end;var d=cw(a,c,1);return b?cw(d,b).end:d},cl.getTotalLength=function(){if(this.type=="path"){if(this.node.getTotalLength)return this.node.getTotalLength();return cu(this.attrs.path)}},cl.getPointAtLength=function(a){if(this.type=="path")return cv(this.attrs.path,a)},cl.getSubpath=function(b,c){if(this.type=="path")return a.getSubpath(this.attrs.path,b,c)};var cx=a.easing_formulas={linear:function(a){return a},"<":function(a){return A(a,1.7)},">":function(a){return A(a,.48)},"<>":function(a){var b=.48-a/1.04,c=w.sqrt(.1734+b*b),d=c-b,e=A(z(d),1/3)*(d<0?-1:1),f=-c-b,g=A(z(f),1/3)*(f<0?-1:1),h=e+g+.5;return(1-h)*3*h*h+h*h*h},backIn:function(a){var b=1.70158;return a*a*((b+1)*a-b)},backOut:function(a){a=a-1;var b=1.70158;return a*a*((b+1)*a+b)+1},elastic:function(a){if(a==!!a)return a;return A(2,-10*a)*w.sin((a-.075)*2*B/.3)+1},bounce:function(a){var b=7.5625,c=2.75,d;a<1/c?d=b*a*a:a<2/c?(a-=1.5/c,d=b*a*a+.75):a<2.5/c?(a-=2.25/c,d=b*a*a+.9375):(a-=2.625/c,d=b*a*a+.984375);return d}};cx.easeIn=cx["ease-in"]=cx["<"],cx.easeOut=cx["ease-out"]=cx[">"],cx.easeInOut=cx["ease-in-out"]=cx["<>"],cx["back-in"]=cx.backIn,cx["back-out"]=cx.backOut;var cy=[],cz=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(a){setTimeout(a,16)},cA=function(){var b=+(new Date),c=0;for(;c<cy.length;c++){var d=cy[c];if(d.el.removed||d.paused)continue;var e=b-d.start,f=d.ms,h=d.easing,i=d.from,j=d.diff,k=d.to,l=d.t,m=d.el,o={},p,r={},s;d.initstatus?(e=(d.initstatus*d.anim.top-d.prev)/(d.percent-d.prev)*f,d.status=d.initstatus,delete d.initstatus,d.stop&&cy.splice(c--,1)):d.status=(d.prev+(d.percent-d.prev)*(e/f))/d.anim.top;if(e<0)continue;if(e<f){var t=h(e/f);for(var u in i)if(i[g](u)){switch(U[u]){case C:p=+i[u]+t*f*j[u];break;case"colour":p="rgb("+[cB(O(i[u].r+t*f*j[u].r)),cB(O(i[u].g+t*f*j[u].g)),cB(O(i[u].b+t*f*j[u].b))].join(",")+")";break;case"path":p=[];for(var v=0,w=i[u].length;v<w;v++){p[v]=[i[u][v][0]];for(var x=1,y=i[u][v].length;x<y;x++)p[v][x]=+i[u][v][x]+t*f*j[u][v][x];p[v]=p[v].join(q)}p=p.join(q);break;case"transform":if(j[u].real){p=[];for(v=0,w=i[u].length;v<w;v++){p[v]=[i[u][v][0]];for(x=1,y=i[u][v].length;x<y;x++)p[v][x]=i[u][v][x]+t*f*j[u][v][x]}}else{var z=function(a){return+i[u][a]+t*f*j[u][a]};p=[["m",z(0),z(1),z(2),z(3),z(4),z(5)]]}break;case"csv":if(u=="clip-rect"){p=[],v=4;while(v--)p[v]=+i[u][v]+t*f*j[u][v]}break;default:var A=[][n](i[u]);p=[],v=m.paper.customAttributes[u].length;while(v--)p[v]=+A[v]+t*f*j[u][v]}o[u]=p}m.attr(o),function(a,b,c){setTimeout(function(){eve("raphael.anim.frame."+a,b,c)})}(m.id,m,d.anim)}else{(function(b,c,d){setTimeout(function(){eve("raphael.anim.frame."+c.id,c,d),eve("raphael.anim.finish."+c.id,c,d),a.is(b,"function")&&b.call(c)})})(d.callback,m,d.anim),m.attr(k),cy.splice(c--,1);if(d.repeat>1&&!d.next){for(s in k)k[g](s)&&(r[s]=d.totalOrigin[s]);d.el.attr(r),cE(d.anim,d.el,d.anim.percents[0],null,d.totalOrigin,d.repeat-1)}d.next&&!d.stop&&cE(d.anim,d.el,d.next,null,d.totalOrigin,d.repeat)}}a.svg&&m&&m.paper&&m.paper.safari(),cy.length&&cz(cA)},cB=function(a){return a>255?255:a<0?0:a};cl.animateWith=function(b,c,d,e,f,g){var h=this;if(h.removed){g&&g.call(h);return h}var i=d instanceof cD?d:a.animation(d,e,f,g),j,k;cE(i,h,i.percents[0],null,h.attr());for(var l=0,m=cy.length;l<m;l++)if(cy[l].anim==c&&cy[l].el==b){cy[m-1].start=cy[l].start;break}return h},cl.onAnimation=function(a){a?eve.on("raphael.anim.frame."+this.id,a):eve.unbind("raphael.anim.frame."+this.id);return this},cD.prototype.delay=function(a){var b=new cD(this.anim,this.ms);b.times=this.times,b.del=+a||0;return b},cD.prototype.repeat=function(a){var b=new cD(this.anim,this.ms);b.del=this.del,b.times=w.floor(x(a,0))||1;return b},a.animation=function(b,c,d,e){if(b instanceof cD)return b;if(a.is(d,"function")||!d)e=e||d||null,d=null;b=Object(b),c=+c||0;var f={},h,i;for(i in b)b[g](i)&&Q(i)!=i&&Q(i)+"%"!=i&&(h=!0,f[i]=b[i]);if(!h)return new cD(b,c);d&&(f.easing=d),e&&(f.callback=e);return new cD({100:f},c)},cl.animate=function(b,c,d,e){var f=this;if(f.removed){e&&e.call(f);return f}var g=b instanceof cD?b:a.animation(b,c,d,e);cE(g,f,g.percents[0],null,f.attr());return f},cl.setTime=function(a,b){a&&b!=null&&this.status(a,y(b,a.ms)/a.ms);return this},cl.status=function(a,b){var c=[],d=0,e,f;if(b!=null){cE(a,this,-1,y(b,1));return this}e=cy.length;for(;d<e;d++){f=cy[d];if(f.el.id==this.id&&(!a||f.anim==a)){if(a)return f.status;c.push({anim:f.anim,status:f.status})}}if(a)return 0;return c},cl.pause=function(a){for(var b=0;b<cy.length;b++)cy[b].el.id==this.id&&(!a||cy[b].anim==a)&&eve("raphael.anim.pause."+this.id,this,cy[b].anim)!==!1&&(cy[b].paused=!0);return this},cl.resume=function(a){for(var b=0;b<cy.length;b++)if(cy[b].el.id==this.id&&(!a||cy[b].anim==a)){var c=cy[b];eve("raphael.anim.resume."+this.id,this,c.anim)!==!1&&(delete c.paused,this.status(c.anim,c.status))}return this},cl.stop=function(a){for(var b=0;b<cy.length;b++)cy[b].el.id==this.id&&(!a||cy[b].anim==a)&&eve("raphael.anim.stop."+this.id,this,cy[b].anim)!==!1&&cy.splice(b--,1);return this},eve.on("raphael.remove",cF),eve.on("raphael.clear",cF),cl.toString=function(){return"Raphaël’s object"};var cG=function(a){this.items=[],this.length=0,this.type="set";if(a)for(var b=0,c=a.length;b<c;b++)a[b]&&(a[b].constructor==cl.constructor||a[b].constructor==cG)&&(this[this.items.length]=this.items[this.items.length]=a[b],this.length++)},cH=cG.prototype;cH.push=function(){var a,b;for(var c=0,d=arguments.length;c<d;c++)a=arguments[c],a&&(a.constructor==cl.constructor||a.constructor==cG)&&(b=this.items.length,this[b]=this.items[b]=a,this.length++);return this},cH.pop=function(){this.length&&delete this[this.length--];return this.items.pop()},cH.forEach=function(a,b){for(var c=0,d=this.items.length;c<d;c++)if(a.call(b,this.items[c],c)===!1)return this;return this};for(var cI in cl)cl[g](cI)&&(cH[cI]=function(a){return function(){var b=arguments;return this.forEach(function(c){c[a][m](c,b)})}}(cI));cH.attr=function(b,c){if(b&&a.is(b,E)&&a.is(b[0],"object"))for(var d=0,e=b.length;d<e;d++)this.items[d].attr(b[d]);else for(var f=0,g=this.items.length;f<g;f++)this.items[f].attr(b,c);return this},cH.clear=function(){while(this.length)this.pop()},cH.splice=function(a,b,c){a=a<0?x(this.length+a,0):a,b=x(0,y(this.length-a,b));var d=[],e=[],f=[],g;for(g=2;g<arguments.length;g++)f.push(arguments[g]);for(g=0;g<b;g++)e.push(this[a+g]);for(;g<this.length-a;g++)d.push(this[a+g]);var h=f.length;for(g=0;g<h+d.length;g++)this.items[a+g]=this[a+g]=g<h?f[g]:d[g-h];g=this.items.length=this.length-=b-h;while(this[g])delete this[g++];return new cG(e)},cH.exclude=function(a){for(var b=0,c=this.length;b<c;b++)if(this[b]==a){this.splice(b,1);return!0}},cH.animate=function(b,c,d,e){(a.is(d,"function")||!d)&&(e=d||null);var f=this.items.length,g=f,h,i=this,j;if(!f)return this;e&&(j=function(){!--f&&e.call(i)}),d=a.is(d,D)?d:j;var k=a.animation(b,c,d,j);h=this.items[--g].animate(k);while(g--)this.items[g]&&!this.items[g].removed&&this.items[g].animateWith(h,k,k);return this},cH.insertAfter=function(a){var b=this.items.length;while(b--)this.items[b].insertAfter(a);return this},cH.getBBox=function(){var a=[],b=[],c=[],d=[];for(var e=this.items.length;e--;)if(!this.items[e].removed){var f=this.items[e].getBBox();a.push(f.x),b.push(f.y),c.push(f.x+f.width),d.push(f.y+f.height)}a=y[m](0,a),b=y[m](0,b),c=x[m](0,c),d=x[m](0,d);return{x:a,y:b,x2:c,y2:d,width:c-a,height:d-b}},cH.clone=function(a){a=new cG;for(var b=0,c=this.items.length;b<c;b++)a.push(this.items[b].clone());return a},cH.toString=function(){return"Raphaël‘s set"},a.registerFont=function(a){if(!a.face)return a;this.fonts=this.fonts||{};var b={w:a.w,face:{},glyphs:{}},c=a.face["font-family"];for(var d in a.face)a.face[g](d)&&(b.face[d]=a.face[d]);this.fonts[c]?this.fonts[c].push(b):this.fonts[c]=[b];if(!a.svg){b.face["units-per-em"]=R(a.face["units-per-em"],10);for(var e in a.glyphs)if(a.glyphs[g](e)){var f=a.glyphs[e];b.glyphs[e]={w:f.w,k:{},d:f.d&&"M"+f.d.replace(/[mlcxtrv]/g,function(a){return{l:"L",c:"C",x:"z",t:"m",r:"l",v:"c"}[a]||"M"})+"z"};if(f.k)for(var h in f.k)f[g](h)&&(b.glyphs[e].k[h]=f.k[h])}}return a},k.getFont=function(b,c,d,e){e=e||"normal",d=d||"normal",c=+c||{normal:400,bold:700,lighter:300,bolder:800}[c]||400;if(!!a.fonts){var f=a.fonts[b];if(!f){var h=new RegExp("(^|\\s)"+b.replace(/[^\w\d\s+!~.:_-]/g,p)+"(\\s|$)","i");for(var i in a.fonts)if(a.fonts[g](i)&&h.test(i)){f=a.fonts[i];break}}var j;if(f)for(var k=0,l=f.length;k<l;k++){j=f[k];if(j.face["font-weight"]==c&&(j.face["font-style"]==d||!j.face["font-style"])&&j.face["font-stretch"]==e)break}return j}},k.print=function(b,d,e,f,g,h,i){h=h||"middle",i=x(y(i||0,1),-1);var j=r(e)[s](p),k=0,l=0,m=p,n;a.is(f,e)&&(f=this.getFont(f));if(f){n=(g||16)/f.face["units-per-em"];var o=f.face.bbox[s](c),q=+o[0],t=o[3]-o[1],u=0,v=+o[1]+(h=="baseline"?t+ +f.face.descent:t/2);for(var w=0,z=j.length;w<z;w++){if(j[w]=="\n")k=0,B=0,l=0,u+=t;else{var A=l&&f.glyphs[j[w-1]]||{},B=f.glyphs[j[w]];k+=l?(A.w||f.w)+(A.k&&A.k[j[w]]||0)+f.w*i:0,l=1}B&&B.d&&(m+=a.transformPath(B.d,["t",k*n,u*n,"s",n,n,q,v,"t",(b-q)/n,(d-v)/n]))}}return this.path(m).attr({fill:"#000",stroke:"none"})},k.add=function(b){if(a.is(b,"array")){var c=this.set(),e=0,f=b.length,h;for(;e<f;e++)h=b[e]||{},d[g](h.type)&&c.push(this[h.type]().attr(h))}return c},a.format=function(b,c){var d=a.is(c,E)?[0][n](c):arguments;b&&a.is(b,D)&&d.length-1&&(b=b.replace(e,function(a,b){return d[++b]==null?p:d[b]}));return b||p},a.fullfill=function(){var a=/\{([^\}]+)\}/g,b=/(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g,c=function(a,c,d){var e=d;c.replace(b,function(a,b,c,d,f){b=b||d,e&&(b in e&&(e=e[b]),typeof e=="function"&&f&&(e=e()))}),e=(e==null||e==d?a:e)+"";return e};return function(b,d){return String(b).replace(a,function(a,b){return c(a,b,d)})}}(),a.ninja=function(){i.was?h.win.Raphael=i.is:delete Raphael;return a},a.st=cH,function(b,c,d){function e(){/in/.test(b.readyState)?setTimeout(e,9):a.eve("raphael.DOMload")}b.readyState==null&&b.addEventListener&&(b.addEventListener(c,d=function(){b.removeEventListener(c,d,!1),b.readyState="complete"},!1),b.readyState="loading"),e()}(document,"DOMContentLoaded"),i.was?h.win.Raphael=a:Raphael=a,eve.on("raphael.DOMload",function(){b=!0})}(),window.Raphael.svg&&function(a){var b="hasOwnProperty",c=String,d=parseFloat,e=parseInt,f=Math,g=f.max,h=f.abs,i=f.pow,j=/[, ]+/,k=a.eve,l="",m=" ",n="http://www.w3.org/1999/xlink",o={block:"M5,0 0,2.5 5,5z",classic:"M5,0 0,2.5 5,5 3.5,3 3.5,2z",diamond:"M2.5,0 5,2.5 2.5,5 0,2.5z",open:"M6,1 1,3.5 6,6",oval:"M2.5,0A2.5,2.5,0,0,1,2.5,5 2.5,2.5,0,0,1,2.5,0z"},p={};a.toString=function(){return"Your browser supports SVG.\nYou are running Raphaël "+this.version};var q=function(d,e){if(e){typeof d=="string"&&(d=q(d));for(var f in e)e[b](f)&&(f.substring(0,6)=="xlink:"?d.setAttributeNS(n,f.substring(6),c(e[f])):d.setAttribute(f,c(e[f])))}else d=a._g.doc.createElementNS("http://www.w3.org/2000/svg",d),d.style&&(d.style.webkitTapHighlightColor="rgba(0,0,0,0)");return d},r=function(b,e){var j="linear",k=b.id+e,m=.5,n=.5,o=b.node,p=b.paper,r=o.style,s=a._g.doc.getElementById(k);if(!s){e=c(e).replace(a._radial_gradient,function(a,b,c){j="radial";if(b&&c){m=d(b),n=d(c);var e=(n>.5)*2-1;i(m-.5,2)+i(n-.5,2)>.25&&(n=f.sqrt(.25-i(m-.5,2))*e+.5)&&n!=.5&&(n=n.toFixed(5)-1e-5*e)}return l}),e=e.split(/\s*\-\s*/);if(j=="linear"){var t=e.shift();t=-d(t);if(isNaN(t))return null;var u=[0,0,f.cos(a.rad(t)),f.sin(a.rad(t))],v=1/(g(h(u[2]),h(u[3]))||1);u[2]*=v,u[3]*=v,u[2]<0&&(u[0]=-u[2],u[2]=0),u[3]<0&&(u[1]=-u[3],u[3]=0)}var w=a._parseDots(e);if(!w)return null;k=k.replace(/[\(\)\s,\xb0#]/g,"_"),b.gradient&&k!=b.gradient.id&&(p.defs.removeChild(b.gradient),delete b.gradient);if(!b.gradient){s=q(j+"Gradient",{id:k}),b.gradient=s,q(s,j=="radial"?{fx:m,fy:n}:{x1:u[0],y1:u[1],x2:u[2],y2:u[3],gradientTransform:b.matrix.invert()}),p.defs.appendChild(s);for(var x=0,y=w.length;x<y;x++)s.appendChild(q("stop",{offset:w[x].offset?w[x].offset:x?"100%":"0%","stop-color":w[x].color||"#fff"}))}}q(o,{fill:"url(#"+k+")",opacity:1,"fill-opacity":1}),r.fill=l,r.opacity=1,r.fillOpacity=1;return 1},s=function(a){var b=a.getBBox(1);q(a.pattern,{patternTransform:a.matrix.invert()+" translate("+b.x+","+b.y+")"})},t=function(d,e,f){if(d.type=="path"){var g=c(e).toLowerCase().split("-"),h=d.paper,i=f?"end":"start",j=d.node,k=d.attrs,m=k["stroke-width"],n=g.length,r="classic",s,t,u,v,w,x=3,y=3,z=5;while(n--)switch(g[n]){case"block":case"classic":case"oval":case"diamond":case"open":case"none":r=g[n];break;case"wide":y=5;break;case"narrow":y=2;break;case"long":x=5;break;case"short":x=2}r=="open"?(x+=2,y+=2,z+=2,u=1,v=f?4:1,w={fill:"none",stroke:k.stroke}):(v=u=x/2,w={fill:k.stroke,stroke:"none"}),d._.arrows?f?(d._.arrows.endPath&&p[d._.arrows.endPath]--,d._.arrows.endMarker&&p[d._.arrows.endMarker]--):(d._.arrows.startPath&&p[d._.arrows.startPath]--,d._.arrows.startMarker&&p[d._.arrows.startMarker]--):d._.arrows={};if(r!="none"){var A="raphael-marker-"+r,B="raphael-marker-"+i+r+x+y;a._g.doc.getElementById(A)?p[A]++:(h.defs.appendChild(q(q("path"),{"stroke-linecap":"round",d:o[r],id:A})),p[A]=1);var C=a._g.doc.getElementById(B),D;C?(p[B]++,D=C.getElementsByTagName("use")[0]):(C=q(q("marker"),{id:B,markerHeight:y,markerWidth:x,orient:"auto",refX:v,refY:y/2}),D=q(q("use"),{"xlink:href":"#"+A,transform:(f?"rotate(180 "+x/2+" "+y/2+") ":l)+"scale("+x/z+","+y/z+")","stroke-width":(1/((x/z+y/z)/2)).toFixed(4)}),C.appendChild(D),h.defs.appendChild(C),p[B]=1),q(D,w);var F=u*(r!="diamond"&&r!="oval");f?(s=d._.arrows.startdx*m||0,t=a.getTotalLength(k.path)-F*m):(s=F*m,t=a.getTotalLength(k.path)-(d._.arrows.enddx*m||0)),w={},w["marker-"+i]="url(#"+B+")";if(t||s)w.d=Raphael.getSubpath(k.path,s,t);q(j,w),d._.arrows[i+"Path"]=A,d._.arrows[i+"Marker"]=B,d._.arrows[i+"dx"]=F,d._.arrows[i+"Type"]=r,d._.arrows[i+"String"]=e}else f?(s=d._.arrows.startdx*m||0,t=a.getTotalLength(k.path)-s):(s=0,t=a.getTotalLength(k.path)-(d._.arrows.enddx*m||0)),d._.arrows[i+"Path"]&&q(j,{d:Raphael.getSubpath(k.path,s,t)}),delete d._.arrows[i+"Path"],delete d._.arrows[i+"Marker"],delete d._.arrows[i+"dx"],delete d._.arrows[i+"Type"],delete d._.arrows[i+"String"];for(w in p)if(p[b](w)&&!p[w]){var G=a._g.doc.getElementById(w);G&&G.parentNode.removeChild(G)}}},u={"":[0],none:[0],"-":[3,1],".":[1,1],"-.":[3,1,1,1],"-..":[3,1,1,1,1,1],". ":[1,3],"- ":[4,3],"--":[8,3],"- .":[4,3,1,3],"--.":[8,3,1,3],"--..":[8,3,1,3,1,3]},v=function(a,b,d){b=u[c(b).toLowerCase()];if(b){var e=a.attrs["stroke-width"]||"1",f={round:e,square:e,butt:0}[a.attrs["stroke-linecap"]||d["stroke-linecap"]]||0,g=[],h=b.length;while(h--)g[h]=b[h]*e+(h%2?1:-1)*f;q(a.node,{"stroke-dasharray":g.join(",")})}},w=function(d,f){var i=d.node,k=d.attrs,m=i.style.visibility;i.style.visibility="hidden";for(var o in f)if(f[b](o)){if(!a._availableAttrs[b](o))continue;var p=f[o];k[o]=p;switch(o){case"blur":d.blur(p);break;case"href":case"title":case"target":var u=i.parentNode;if(u.tagName.toLowerCase()!="a"){var w=q("a");u.insertBefore(w,i),w.appendChild(i),u=w}o=="target"?u.setAttributeNS(n,"show",p=="blank"?"new":p):u.setAttributeNS(n,o,p);break;case"cursor":i.style.cursor=p;break;case"transform":d.transform(p);break;case"arrow-start":t(d,p);break;case"arrow-end":t(d,p,1);break;case"clip-rect":var x=c(p).split(j);if(x.length==4){d.clip&&d.clip.parentNode.parentNode.removeChild(d.clip.parentNode);var z=q("clipPath"),A=q("rect");z.id=a.createUUID(),q(A,{x:x[0],y:x[1],width:x[2],height:x[3]}),z.appendChild(A),d.paper.defs.appendChild(z),q(i,{"clip-path":"url(#"+z.id+")"}),d.clip=A}if(!p){var B=i.getAttribute("clip-path");if(B){var C=a._g.doc.getElementById(B.replace(/(^url\(#|\)$)/g,l));C&&C.parentNode.removeChild(C),q(i,{"clip-path":l}),delete d.clip}}break;case"path":d.type=="path"&&(q(i,{d:p?k.path=a._pathToAbsolute(p):"M0,0"}),d._.dirty=1,d._.arrows&&("startString"in d._.arrows&&t(d,d._.arrows.startString),"endString"in d._.arrows&&t(d,d._.arrows.endString,1)));break;case"width":i.setAttribute(o,p),d._.dirty=1;if(k.fx)o="x",p=k.x;else break;case"x":k.fx&&(p=-k.x-(k.width||0));case"rx":if(o=="rx"&&d.type=="rect")break;case"cx":i.setAttribute(o,p),d.pattern&&s(d),d._.dirty=1;break;case"height":i.setAttribute(o,p),d._.dirty=1;if(k.fy)o="y",p=k.y;else break;case"y":k.fy&&(p=-k.y-(k.height||0));case"ry":if(o=="ry"&&d.type=="rect")break;case"cy":i.setAttribute(o,p),d.pattern&&s(d),d._.dirty=1;break;case"r":d.type=="rect"?q(i,{rx:p,ry:p}):i.setAttribute(o,p),d._.dirty=1;break;case"src":d.type=="image"&&i.setAttributeNS(n,"href",p);break;case"stroke-width":if(d._.sx!=1||d._.sy!=1)p/=g(h(d._.sx),h(d._.sy))||1;d.paper._vbSize&&(p*=d.paper._vbSize),i.setAttribute(o,p),k["stroke-dasharray"]&&v(d,k["stroke-dasharray"],f),d._.arrows&&("startString"in d._.arrows&&t(d,d._.arrows.startString),"endString"in d._.arrows&&t(d,d._.arrows.endString,1));break;case"stroke-dasharray":v(d,p,f);break;case"fill":var D=c(p).match(a._ISURL);if(D){z=q("pattern");var F=q("image");z.id=a.createUUID(),q(z,{x:0,y:0,patternUnits:"userSpaceOnUse",height:1,width:1}),q(F,{x:0,y:0,"xlink:href":D[1]}),z.appendChild(F),function(b){a._preload(D[1],function(){var a=this.offsetWidth,c=this.offsetHeight;q(b,{width:a,height:c}),q(F,{width:a,height:c}),d.paper.safari()})}(z),d.paper.defs.appendChild(z),q(i,{fill:"url(#"+z.id+")"}),d.pattern=z,d.pattern&&s(d);break}var G=a.getRGB(p);if(!G.error)delete f.gradient,delete k.gradient,!a.is(k.opacity,"undefined")&&a.is(f.opacity,"undefined")&&q(i,{opacity:k.opacity}),!a.is(k["fill-opacity"],"undefined")&&a.is(f["fill-opacity"],"undefined")&&q(i,{"fill-opacity":k["fill-opacity"]});else if((d.type=="circle"||d.type=="ellipse"||c(p).charAt()!="r")&&r(d,p)){if("opacity"in k||"fill-opacity"in k){var H=a._g.doc.getElementById(i.getAttribute("fill").replace(/^url\(#|\)$/g,l));if(H){var I=H.getElementsByTagName("stop");q(I[I.length-1],{"stop-opacity":("opacity"in k?k.opacity:1)*("fill-opacity"in k?k["fill-opacity"]:1)})}}k.gradient=p,k.fill="none";break}G[b]("opacity")&&q(i,{"fill-opacity":G.opacity>1?G.opacity/100:G.opacity});case"stroke":G=a.getRGB(p),i.setAttribute(o,G.hex),o=="stroke"&&G[b]("opacity")&&q(i,{"stroke-opacity":G.opacity>1?G.opacity/100:G.opacity}),o=="stroke"&&d._.arrows&&("startString"in d._.arrows&&t(d,d._.arrows.startString),"endString"in d._.arrows&&t(d,d._.arrows.endString,1));break;case"gradient":(d.type=="circle"||d.type=="ellipse"||c(p).charAt()!="r")&&r(d,p);break;case"opacity":k.gradient&&!k[b]("stroke-opacity")&&q(i,{"stroke-opacity":p>1?p/100:p});case"fill-opacity":if(k.gradient){H=a._g.doc.getElementById(i.getAttribute("fill").replace(/^url\(#|\)$/g,l)),H&&(I=H.getElementsByTagName("stop"),q(I[I.length-1],{"stop-opacity":p}));break};default:o=="font-size"&&(p=e(p,10)+"px");var J=o.replace(/(\-.)/g,function(a){return a.substring(1).toUpperCase()});i.style[J]=p,d._.dirty=1,i.setAttribute(o,p)}}y(d,f),i.style.visibility=m},x=1.2,y=function(d,f){if(d.type=="text"&&!!(f[b]("text")||f[b]("font")||f[b]("font-size")||f[b]("x")||f[b]("y"))){var g=d.attrs,h=d.node,i=h.firstChild?e(a._g.doc.defaultView.getComputedStyle(h.firstChild,l).getPropertyValue("font-size"),10):10;if(f[b]("text")){g.text=f.text;while(h.firstChild)h.removeChild(h.firstChild);var j=c(f.text).split("\n"),k=[],m;for(var n=0,o=j.length;n<o;n++)m=q("tspan"),n&&q(m,{dy:i*x,x:g.x}),m.appendChild(a._g.doc.createTextNode(j[n])),h.appendChild(m),k[n]=m}else{k=h.getElementsByTagName("tspan");for(n=0,o=k.length;n<o;n++)n?q(k[n],{dy:i*x,x:g.x}):q(k[0],{dy:0})}q(h,{x:g.x,y:g.y}),d._.dirty=1;var p=d._getBBox(),r=g.y-(p.y+p.height/2);r&&a.is(r,"finite")&&q(k[0],{dy:r})}},z=function(b,c){var d=0,e=0;this[0]=this.node=b,b.raphael=!0,this.id=a._oid++,b.raphaelid=this.id,this.matrix=a.matrix(),this.realPath=null,this.paper=c,this.attrs=this.attrs||{},this._={transform:[],sx:1,sy:1,deg:0,dx:0,dy:0,dirty:1},!c.bottom&&(c.bottom=this),this.prev=c.top,c.top&&(c.top.next=this),c.top=this,this.next=null},A=a.el;z.prototype=A,A.constructor=z,a._engine.path=function(a,b){var c=q("path");b.canvas&&b.canvas.appendChild(c);var d=new z(c,b);d.type="path",w(d,{fill:"none",stroke:"#000",path:a});return d},A.rotate=function(a,b,e){if(this.removed)return this;a=c(a).split(j),a.length-1&&(b=d(a[1]),e=d(a[2])),a=d(a[0]),e==null&&(b=e);if(b==null||e==null){var f=this.getBBox(1);b=f.x+f.width/2,e=f.y+f.height/2}this.transform(this._.transform.concat([["r",a,b,e]]));return this},A.scale=function(a,b,e,f){if(this.removed)return this;a=c(a).split(j),a.length-1&&(b=d(a[1]),e=d(a[2]),f=d(a[3])),a=d(a[0]),b==null&&(b=a),f==null&&(e=f);if(e==null||f==null)var g=this.getBBox(1);e=e==null?g.x+g.width/2:e,f=f==null?g.y+g.height/2:f,this.transform(this._.transform.concat([["s",a,b,e,f]]));return this},A.translate=function(a,b){if(this.removed)return this;a=c(a).split(j),a.length-1&&(b=d(a[1])),a=d(a[0])||0,b=+b||0,this.transform(this._.transform.concat([["t",a,b]]));return this},A.transform=function(c){var d=this._;if(c==null)return d.transform;a._extractTransform(this,c),this.clip&&q(this.clip,{transform:this.matrix.invert()}),this.pattern&&s(this),this.node&&q(this.node,{transform:this.matrix});if(d.sx!=1||d.sy!=1){var e=this.attrs[b]("stroke-width")?this.attrs["stroke-width"]:1;this.attr({"stroke-width":e})}return this},A.hide=function(){!this.removed&&this.paper.safari(this.node.style.display="none");return this},A.show=function(){!this.removed&&this.paper.safari(this.node.style.display="");return this},A.remove=function(){if(!this.removed&&!!this.node.parentNode){var b=this.paper;b.__set__&&b.__set__.exclude(this),k.unbind("raphael.*.*."+this.id),this.gradient&&b.defs.removeChild(this.gradient),a._tear(this,b),this.node.parentNode.tagName.toLowerCase()=="a"?this.node.parentNode.parentNode.removeChild(this.node.parentNode):this.node.parentNode.removeChild(this.node);for(var c in this)this[c]=typeof this[c]=="function"?a._removedFactory(c):null;this.removed=!0}},A._getBBox=function(){if(this.node.style.display=="none"){this.show();var a=!0}var b={};try{b=this.node.getBBox()}catch(c){}finally{b=b||{}}a&&this.hide();return b},A.attr=function(c,d){if(this.removed)return this;if(c==null){var e={};for(var f in this.attrs)this.attrs[b](f)&&(e[f]=this.attrs[f]);e.gradient&&e.fill=="none"&&(e.fill=e.gradient)&&delete e.gradient,e.transform=this._.transform;return e}if(d==null&&a.is(c,"string")){if(c=="fill"&&this.attrs.fill=="none"&&this.attrs.gradient)return this.attrs.gradient;if(c=="transform")return this._.transform;var g=c.split(j),h={};for(var i=0,l=g.length;i<l;i++)c=g[i],c in this.attrs?h[c]=this.attrs[c]:a.is(this.paper.customAttributes[c],"function")?h[c]=this.paper.customAttributes[c].def:h[c]=a._availableAttrs[c];return l-1?h:h[g[0]]}if(d==null&&a.is(c,"array")){h={};for(i=0,l=c.length;i<l;i++)h[c[i]]=this.attr(c[i]);return h}if(d!=null){var m={};m[c]=d}else c!=null&&a.is(c,"object")&&(m=c);for(var n in m)k("raphael.attr."+n+"."+this.id,this,m[n]);for(n in this.paper.customAttributes)if(this.paper.customAttributes[b](n)&&m[b](n)&&a.is(this.paper.customAttributes[n],"function")){var o=this.paper.customAttributes[n].apply(this,[].concat(m[n]));this.attrs[n]=m[n];for(var p in o)o[b](p)&&(m[p]=o[p])}w(this,m);return this},A.toFront=function(){if(this.removed)return this;this.node.parentNode.tagName.toLowerCase()=="a"?this.node.parentNode.parentNode.appendChild(this.node.parentNode):this.node.parentNode.appendChild(this.node);var b=this.paper;b.top!=this&&a._tofront(this,b);return this},A.toBack=function(){if(this.removed)return this;var b=this.node.parentNode;b.tagName.toLowerCase()=="a"?b.parentNode.insertBefore(this.node.parentNode,this.node.parentNode.parentNode.firstChild):b.firstChild!=this.node&&b.insertBefore(this.node,this.node.parentNode.firstChild),a._toback(this,this.paper);var c=this.paper;return this},A.insertAfter=function(b){if(this.removed)return this;var c=b.node||b[b.length-1].node;c.nextSibling?c.parentNode.insertBefore(this.node,c.nextSibling):c.parentNode.appendChild(this.node),a._insertafter(this,b,this.paper);return this},A.insertBefore=function(b){if(this.removed)return this;var c=b.node||b[0].node;c.parentNode.insertBefore(this.node,c),a._insertbefore(this,b,this.paper);return this},A.blur=function(b){var c=this;if(+b!==0){var d=q("filter"),e=q("feGaussianBlur");c.attrs.blur=b,d.id=a.createUUID(),q(e,{stdDeviation:+b||1.5}),d.appendChild(e),c.paper.defs.appendChild(d),c._blur=d,q(c.node,{filter:"url(#"+d.id+")"})}else c._blur&&(c._blur.parentNode.removeChild(c._blur),delete c._blur,delete c.attrs.blur),c.node.removeAttribute("filter")},a._engine.circle=function(a,b,c,d){var e=q("circle");a.canvas&&a.canvas.appendChild(e);var f=new z(e,a);f.attrs={cx:b,cy:c,r:d,fill:"none",stroke:"#000"},f.type="circle",q(e,f.attrs);return f},a._engine.rect=function(a,b,c,d,e,f){var g=q("rect");a.canvas&&a.canvas.appendChild(g);var h=new z(g,a);h.attrs={x:b,y:c,width:d,height:e,r:f||0,rx:f||0,ry:f||0,fill:"none",stroke:"#000"},h.type="rect",q(g,h.attrs);return h},a._engine.ellipse=function(a,b,c,d,e){var f=q("ellipse");a.canvas&&a.canvas.appendChild(f);var g=new z(f,a);g.attrs={cx:b,cy:c,rx:d,ry:e,fill:"none",stroke:"#000"},g.type="ellipse",q(f,g.attrs);return g},a._engine.image=function(a,b,c,d,e,f){var g=q("image");q(g,{x:c,y:d,width:e,height:f,preserveAspectRatio:"none"}),g.setAttributeNS(n,"href",b),a.canvas&&a.canvas.appendChild(g);var h=new z(g,a);h.attrs={x:c,y:d,width:e,height:f,src:b},h.type="image";return h},a._engine.text=function(b,c,d,e){var f=q("text");b.canvas&&b.canvas.appendChild(f);var g=new z(f,b);g.attrs={x:c,y:d,"text-anchor":"middle",text:e,font:a._availableAttrs.font,stroke:"none",fill:"#000"},g.type="text",w(g,g.attrs);return g},a._engine.setSize=function(a,b){this.width=a||this.width,this.height=b||this.height,this.canvas.setAttribute("width",this.width),this.canvas.setAttribute("height",this.height),this._viewBox&&this.setViewBox.apply(this,this._viewBox);return this},a._engine.create=function(){var b=a._getContainer.apply(0,arguments),c=b&&b.container,d=b.x,e=b.y,f=b.width,g=b.height;if(!c)throw new Error("SVG container not found.");var h=q("svg"),i="overflow:hidden;",j;d=d||0,e=e||0,f=f||512,g=g||342,q(h,{height:g,version:1.1,width:f,xmlns:"http://www.w3.org/2000/svg"}),c==1?(h.style.cssText=i+"position:absolute;left:"+d+"px;top:"+e+"px",a._g.doc.body.appendChild(h),j=1):(h.style.cssText=i+"position:relative",c.firstChild?c.insertBefore(h,c.firstChild):c.appendChild(h)),c=new a._Paper,c.width=f,c.height=g,c.canvas=h,c.clear(),c._left=c._top=0,j&&(c.renderfix=function(){}),c.renderfix();return c},a._engine.setViewBox=function(a,b,c,d,e){k("raphael.setViewBox",this,this._viewBox,[a,b,c,d,e]);var f=g(c/this.width,d/this.height),h=this.top,i=e?"meet":"xMinYMin",j,l;a==null?(this._vbSize&&(f=1),delete this._vbSize,j="0 0 "+this.width+m+this.height):(this._vbSize=f,j=a+m+b+m+c+m+d),q(this.canvas,{viewBox:j,preserveAspectRatio:i});while(f&&h)l="stroke-width"in h.attrs?h.attrs["stroke-width"]:1,h.attr({"stroke-width":l}),h._.dirty=1,h._.dirtyT=1,h=h.prev;this._viewBox=[a,b,c,d,!!e];return this},a.prototype.renderfix=function(){var a=this.canvas,b=a.style,c;try{c=a.getScreenCTM()||a.createSVGMatrix()}catch(d){c=a.createSVGMatrix()}var e=-c.e%1,f=-c.f%1;if(e||f)e&&(this._left=(this._left+e)%1,b.left=this._left+"px"),f&&(this._top=(this._top+f)%1,b.top=this._top+"px")},a.prototype.clear=function(){a.eve("raphael.clear",this);var b=this.canvas;while(b.firstChild)b.removeChild(b.firstChild);this.bottom=this.top=null,(this.desc=q("desc")).appendChild(a._g.doc.createTextNode("Created with Raphaël "+a.version)),b.appendChild(this.desc),b.appendChild(this.defs=q("defs"))},a.prototype.remove=function(){k("raphael.remove",this),this.canvas.parentNode&&this.canvas.parentNode.removeChild(this.canvas);for(var b in this)this[b]=typeof this[b]=="function"?a._removedFactory(b):null};var B=a.st;for(var C in A)A[b](C)&&!B[b](C)&&(B[C]=function(a){return function(){var b=arguments;return this.forEach(function(c){c[a].apply(c,b)})}}(C))}(window.Raphael),window.Raphael.vml&&function(a){var b="hasOwnProperty",c=String,d=parseFloat,e=Math,f=e.round,g=e.max,h=e.min,i=e.abs,j="fill",k=/[, ]+/,l=a.eve,m=" progid:DXImageTransform.Microsoft",n=" ",o="",p={M:"m",L:"l",C:"c",Z:"x",m:"t",l:"r",c:"v",z:"x"},q=/([clmz]),?([^clmz]*)/gi,r=/ progid:\S+Blur\([^\)]+\)/g,s=/-?[^,\s-]+/g,t="position:absolute;left:0;top:0;width:1px;height:1px",u=21600,v={path:1,rect:1,image:1},w={circle:1,ellipse:1},x=function(b){var d=/[ahqstv]/ig,e=a._pathToAbsolute;c(b).match(d)&&(e=a._path2curve),d=/[clmz]/g;if(e==a._pathToAbsolute&&!c(b).match(d)){var g=c(b).replace(q,function(a,b,c){var d=[],e=b.toLowerCase()=="m",g=p[b];c.replace(s,function(a){e&&d.length==2&&(g+=d+p[b=="m"?"l":"L"],d=[]),d.push(f(a*u))});return g+d});return g}var h=e(b),i,j;g=[];for(var k=0,l=h.length;k<l;k++){i=h[k],j=h[k][0].toLowerCase(),j=="z"&&(j="x");for(var m=1,r=i.length;m<r;m++)j+=f(i[m]*u)+(m!=r-1?",":o);g.push(j)}return g.join(n)},y=function(b,c,d){var e=a.matrix();e.rotate(-b,.5,.5);return{dx:e.x(c,d),dy:e.y(c,d)}},z=function(a,b,c,d,e,f){var g=a._,h=a.matrix,k=g.fillpos,l=a.node,m=l.style,o=1,p="",q,r=u/b,s=u/c;m.visibility="hidden";if(!!b&&!!c){l.coordsize=i(r)+n+i(s),m.rotation=f*(b*c<0?-1:1);if(f){var t=y(f,d,e);d=t.dx,e=t.dy}b<0&&(p+="x"),c<0&&(p+=" y")&&(o=-1),m.flip=p,l.coordorigin=d*-r+n+e*-s;if(k||g.fillsize){var v=l.getElementsByTagName(j);v=v&&v[0],l.removeChild(v),k&&(t=y(f,h.x(k[0],k[1]),h.y(k[0],k[1])),v.position=t.dx*o+n+t.dy*o),g.fillsize&&(v.size=g.fillsize[0]*i(b)+n+g.fillsize[1]*i(c)),l.appendChild(v)}m.visibility="visible"}};a.toString=function(){return"Your browser doesn’t support SVG. Falling down to VML.\nYou are running Raphaël "+this.version};var A=function(a,b,d){var e=c(b).toLowerCase().split("-"),f=d?"end":"start",g=e.length,h="classic",i="medium",j="medium";while(g--)switch(e[g]){case"block":case"classic":case"oval":case"diamond":case"open":case"none":h=e[g];break;case"wide":case"narrow":j=e[g];break;case"long":case"short":i=e[g]}var k=a.node.getElementsByTagName("stroke")[0];k[f+"arrow"]=h,k[f+"arrowlength"]=i,k[f+"arrowwidth"]=j},B=function(e,i){e.attrs=e.attrs||{};var l=e.node,m=e.attrs,p=l.style,q,r=v[e.type]&&(i.x!=m.x||i.y!=m.y||i.width!=m.width||i.height!=m.height||i.cx!=m.cx||i.cy!=m.cy||i.rx!=m.rx||i.ry!=m.ry||i.r!=m.r),s=w[e.type]&&(m.cx!=i.cx||m.cy!=i.cy||m.r!=i.r||m.rx!=i.rx||m.ry!=i.ry),t=e;for(var y in i)i[b](y)&&(m[y]=i[y]);r&&(m.path=a._getPath[e.type](e),e._.dirty=1),i.href&&(l.href=i.href),i.title&&(l.title=i.title),i.target&&(l.target=i.target),i.cursor&&(p.cursor=i.cursor),"blur"in i&&e.blur(i.blur);if(i.path&&e.type=="path"||r)l.path=x(~c(m.path).toLowerCase().indexOf("r")?a._pathToAbsolute(m.path):m.path),e.type=="image"&&(e._.fillpos=[m.x,m.y],e._.fillsize=[m.width,m.height],z(e,1,1,0,0,0));"transform"in i&&e.transform(i.transform);if(s){var B=+m.cx,D=+m.cy,E=+m.rx||+m.r||0,G=+m.ry||+m.r||0;l.path=a.format("ar{0},{1},{2},{3},{4},{1},{4},{1}x",f((B-E)*u),f((D-G)*u),f((B+E)*u),f((D+G)*u),f(B*u))}if("clip-rect"in i){var H=c(i["clip-rect"]).split(k);if(H.length==4){H[2]=+H[2]+ +H[0],H[3]=+H[3]+ +H[1];var I=l.clipRect||a._g.doc.createElement("div"),J=I.style;J.clip=a.format("rect({1}px {2}px {3}px {0}px)",H),l.clipRect||(J.position="absolute",J.top=0,J.left=0,J.width=e.paper.width+"px",J.height=e.paper.height+"px",l.parentNode.insertBefore(I,l),I.appendChild(l),l.clipRect=I)}i["clip-rect"]||l.clipRect&&(l.clipRect.style.clip="auto")}if(e.textpath){var K=e.textpath.style;i.font&&(K.font=i.font),i["font-family"]&&(K.fontFamily='"'+i["font-family"].split(",")[0].replace(/^['"]+|['"]+$/g,o)+'"'),i["font-size"]&&(K.fontSize=i["font-size"]),i["font-weight"]&&(K.fontWeight=i["font-weight"]),i["font-style"]&&(K.fontStyle=i["font-style"])}"arrow-start"in i&&A(t,i["arrow-start"]),"arrow-end"in i&&A(t,i["arrow-end"],1);if(i.opacity!=null||i["stroke-width"]!=null||i.fill!=null||i.src!=null||i.stroke!=null||i["stroke-width"]!=null||i["stroke-opacity"]!=null||i["fill-opacity"]!=null||i["stroke-dasharray"]!=null||i["stroke-miterlimit"]!=null||i["stroke-linejoin"]!=null||i["stroke-linecap"]!=null){var L=l.getElementsByTagName(j),M=!1;L=L&&L[0],!L&&(M=L=F(j)),e.type=="image"&&i.src&&(L.src=i.src),i.fill&&(L.on=!0);if(L.on==null||i.fill=="none"||i.fill===null)L.on=!1;if(L.on&&i.fill){var N=c(i.fill).match(a._ISURL);if(N){L.parentNode==l&&l.removeChild(L),L.rotate=!0,L.src=N[1],L.type="tile";var O=e.getBBox(1);L.position=O.x+n+O.y,e._.fillpos=[O.x,O.y],a._preload(N[1],function(){e._.fillsize=[this.offsetWidth,this.offsetHeight]})}else L.color=a.getRGB(i.fill).hex,L.src=o,L.type="solid",a.getRGB(i.fill).error&&(t.type in{circle:1,ellipse:1}||c(i.fill).charAt()!="r")&&C(t,i.fill,L)&&(m.fill="none",m.gradient=i.fill,L.rotate=!1)}if("fill-opacity"in i||"opacity"in i){var P=((+m["fill-opacity"]+1||2)-1)*((+m.opacity+1||2)-1)*((+a.getRGB(i.fill).o+1||2)-1);P=h(g(P,0),1),L.opacity=P,L.src&&(L.color="none")}l.appendChild(L);var Q=l.getElementsByTagName("stroke")&&l.getElementsByTagName("stroke")[0],T=!1;!Q&&(T=Q=F("stroke"));if(i.stroke&&i.stroke!="none"||i["stroke-width"]||i["stroke-opacity"]!=null||i["stroke-dasharray"]||i["stroke-miterlimit"]||i["stroke-linejoin"]||i["stroke-linecap"])Q.on=!0;(i.stroke=="none"||i.stroke===null||Q.on==null||i.stroke==0||i["stroke-width"]==0)&&(Q.on=!1);var U=a.getRGB(i.stroke);Q.on&&i.stroke&&(Q.color=U.hex),P=((+m["stroke-opacity"]+1||2)-1)*((+m.opacity+1||2)-1)*((+U.o+1||2)-1);var V=(d(i["stroke-width"])||1)*.75;P=h(g(P,0),1),i["stroke-width"]==null&&(V=m["stroke-width"]),i["stroke-width"]&&(Q.weight=V),V&&V<1&&(P*=V)&&(Q.weight=1),Q.opacity=P,i["stroke-linejoin"]&&(Q.joinstyle=i["stroke-linejoin"]||"miter"),Q.miterlimit=i["stroke-miterlimit"]||8,i["stroke-linecap"]&&(Q.endcap=i["stroke-linecap"]=="butt"?"flat":i["stroke-linecap"]=="square"?"square":"round");if(i["stroke-dasharray"]){var W={"-":"shortdash",".":"shortdot","-.":"shortdashdot","-..":"shortdashdotdot",". ":"dot","- ":"dash","--":"longdash","- .":"dashdot","--.":"longdashdot","--..":"longdashdotdot"};Q.dashstyle=W[b](i["stroke-dasharray"])?W[i["stroke-dasharray"]]:o}T&&l.appendChild(Q)}if(t.type=="text"){t.paper.canvas.style.display=o;var X=t.paper.span,Y=100,Z=m.font&&m.font.match(/\d+(?:\.\d*)?(?=px)/);p=X.style,m.font&&(p.font=m.font),m["font-family"]&&(p.fontFamily=m["font-family"]),m["font-weight"]&&(p.fontWeight=m["font-weight"]),m["font-style"]&&(p.fontStyle=m["font-style"]),Z=d(m["font-size"]||Z&&Z[0])||10,p.fontSize=Z*Y+"px",t.textpath.string&&(X.innerHTML=c(t.textpath.string).replace(/</g,"<").replace(/&/g,"&").replace(/\n/g,"<br>"));var $=X.getBoundingClientRect();t.W=m.w=($.right-$.left)/Y,t.H=m.h=($.bottom-$.top)/Y,t.X=m.x,t.Y=m.y+t.H/2,("x"in i||"y"in i)&&(t.path.v=a.format("m{0},{1}l{2},{1}",f(m.x*u),f(m.y*u),f(m.x*u)+1));var _=["x","y","text","font","font-family","font-weight","font-style","font-size"];for(var ba=0,bb=_.length;ba<bb;ba++)if(_[ba]in i){t._.dirty=1;break}switch(m["text-anchor"]){case"start":t.textpath.style["v-text-align"]="left",t.bbx=t.W/2;break;case"end":t.textpath.style["v-text-align"]="right",t.bbx=-t.W/2;break;default:t.textpath.style["v-text-align"]="center",t.bbx=0}t.textpath.style["v-text-kern"]=!0}},C=function(b,f,g){b.attrs=b.attrs||{};var h=b.attrs,i=Math.pow,j,k,l="linear",m=".5 .5";b.attrs.gradient=f,f=c(f).replace(a._radial_gradient,function(a,b,c){l="radial",b&&c&&(b=d(b),c=d(c),i(b-.5,2)+i(c-.5,2)>.25&&(c=e.sqrt(.25-i(b-.5,2))*((c>.5)*2-1)+.5),m=b+n+c);return o}),f=f.split(/\s*\-\s*/);if(l=="linear"){var p=f.shift();p=-d(p);if(isNaN(p))return null}var q=a._parseDots(f);if(!q)return null;b=b.shape||b.node;if(q.length){b.removeChild(g),g.on=!0,g.method="none",g.color=q[0].color,g.color2=q[q.length-1].color;var r=[];for(var s=0,t=q.length;s<t;s++)q[s].offset&&r.push(q[s].offset+n+q[s].color);g.colors=r.length?r.join():"0% "+g.color,l=="radial"?(g.type="gradientTitle",g.focus="100%",g.focussize="0 0",g.focusposition=m,g.angle=0):(g.type="gradient",g.angle=(270-p)%360),b.appendChild(g)}return 1},D=function(b,c){this[0]=this.node=b,b.raphael=!0,this.id=a._oid++,b.raphaelid=this.id,this.X=0,this.Y=0,this.attrs={},this.paper=c,this.matrix=a.matrix(),this._={transform:[],sx:1,sy:1,dx:0,dy:0,deg:0,dirty:1,dirtyT:1},!c.bottom&&(c.bottom=this),this.prev=c.top,c.top&&(c.top.next=this),c.top=this,this.next=null},E=a.el;D.prototype=E,E.constructor=D,E.transform=function(b){if(b==null)return this._.transform;var d=this.paper._viewBoxShift,e=d?"s"+[d.scale,d.scale]+"-1-1t"+[d.dx,d.dy]:o,f;d&&(f=b=c(b).replace(/\.{3}|\u2026/g,this._.transform||o)),a._extractTransform(this,e+b);var g=this.matrix.clone(),h=this.skew,i=this.node,j,k=~c(this.attrs.fill).indexOf("-"),l=!c(this.attrs.fill).indexOf("url(");g.translate(-0.5,-0.5);if(l||k||this.type=="image"){h.matrix="1 0 0 1",h.offset="0 0",j=g.split();if(k&&j.noRotation||!j.isSimple){i.style.filter=g.toFilter();var m=this.getBBox(),p=this.getBBox(1),q=m.x-p.x,r=m.y-p.y;i.coordorigin=q*-u+n+r*-u,z(this,1,1,q,r,0)}else i.style.filter=o,z(this,j.scalex,j.scaley,j.dx,j.dy,j.rotate)}else i.style.filter=o,h.matrix=c(g),h.offset=g.offset();f&&(this._.transform=f);return this},E.rotate=function(a,b,e){if(this.removed)return this;if(a!=null){a=c(a).split(k),a.length-1&&(b=d(a[1]),e=d(a[2])),a=d(a[0]),e==null&&(b=e);if(b==null||e==null){var f=this.getBBox(1);b=f.x+f.width/2,e=f.y+f.height/2}this._.dirtyT=1,this.transform(this._.transform.concat([["r",a,b,e]]));return this}},E.translate=function(a,b){if(this.removed)return this;a=c(a).split(k),a.length-1&&(b=d(a[1])),a=d(a[0])||0,b=+b||0,this._.bbox&&(this._.bbox.x+=a,this._.bbox.y+=b),this.transform(this._.transform.concat([["t",a,b]]));return this},E.scale=function(a,b,e,f){if(this.removed)return this;a=c(a).split(k),a.length-1&&(b=d(a[1]),e=d(a[2]),f=d(a[3]),isNaN(e)&&(e=null),isNaN(f)&&(f=null)),a=d(a[0]),b==null&&(b=a),f==null&&(e=f);if(e==null||f==null)var g=this.getBBox(1);e=e==null?g.x+g.width/2:e,f=f==null?g.y+g.height/2:f,this.transform(this._.transform.concat([["s",a,b,e,f]])),this._.dirtyT=1;return this},E.hide=function(){!this.removed&&(this.node.style.display="none");return this},E.show=function(){!this.removed&&(this.node.style.display=o);return this},E._getBBox=function(){if(this.removed)return{};return{x:this.X+(this.bbx||0)-this.W/2,y:this.Y-this.H,width:this.W,height:this.H}},E.remove=function(){if(!this.removed&&!!this.node.parentNode){this.paper.__set__&&this.paper.__set__.exclude(this),a.eve.unbind("raphael.*.*."+this.id),a._tear(this,this.paper),this.node.parentNode.removeChild(this.node),this.shape&&this.shape.parentNode.removeChild(this.shape);for(var b in this)this[b]=typeof this[b]=="function"?a._removedFactory(b):null;this.removed=!0}},E.attr=function(c,d){if(this.removed)return this;if(c==null){var e={};for(var f in this.attrs)this.attrs[b](f)&&(e[f]=this.attrs[f]);e.gradient&&e.fill=="none"&&(e.fill=e.gradient)&&delete e.gradient,e.transform=this._.transform;return e}if(d==null&&a.is(c,"string")){if(c==j&&this.attrs.fill=="none"&&this.attrs.gradient)return this.attrs.gradient;var g=c.split(k),h={};for(var i=0,m=g.length;i<m;i++)c=g[i],c in this.attrs?h[c]=this.attrs[c]:a.is(this.paper.customAttributes[c],"function")?h[c]=this.paper.customAttributes[c].def:h[c]=a._availableAttrs[c];return m-1?h:h[g[0]]}if(this.attrs&&d==null&&a.is(c,"array")){h={};for(i=0,m=c.length;i<m;i++)h[c[i]]=this.attr(c[i]);return h}var n;d!=null&&(n={},n[c]=d),d==null&&a.is(c,"object")&&(n=c);for(var o in n)l("raphael.attr."+o+"."+this.id,this,n[o]);if(n){for(o in this.paper.customAttributes)if(this.paper.customAttributes[b](o)&&n[b](o)&&a.is(this.paper.customAttributes[o],"function")){var p=this.paper.customAttributes[o].apply(this,[].concat(n[o]));this.attrs[o]=n[o];for(var q in p)p[b](q)&&(n[q]=p[q])}n.text&&this.type=="text"&&(this.textpath.string=n.text),B(this,n)}return this},E.toFront=function(){!this.removed&&this.node.parentNode.appendChild(this.node),this.paper&&this.paper.top!=this&&a._tofront(this,this.paper);return this},E.toBack=function(){if(this.removed)return this;this.node.parentNode.firstChild!=this.node&&(this.node.parentNode.insertBefore(this.node,this.node.parentNode.firstChild),a._toback(this,this.paper));return this},E.insertAfter=function(b){if(this.removed)return this;b.constructor==a.st.constructor&&(b=b[b.length-1]),b.node.nextSibling?b.node.parentNode.insertBefore(this.node,b.node.nextSibling):b.node.parentNode.appendChild(this.node),a._insertafter(this,b,this.paper);return this},E.insertBefore=function(b){if(this.removed)return this;b.constructor==a.st.constructor&&(b=b[0]),b.node.parentNode.insertBefore(this.node,b.node),a._insertbefore(this,b,this.paper);return this},E.blur=function(b){var c=this.node.runtimeStyle,d=c.filter;d=d.replace(r,o),+b!==0?(this.attrs.blur=b,c.filter=d+n+m+".Blur(pixelradius="+(+b||1.5)+")",c.margin=a.format("-{0}px 0 0 -{0}px",f(+b||1.5))):(c.filter=d,c.margin=0,delete this.attrs.blur)},a._engine.path=function(a,b){var c=F("shape");c.style.cssText=t,c.coordsize=u+n+u,c.coordorigin=b.coordorigin;var d=new D(c,b),e={fill:"none",stroke:"#000"};a&&(e.path=a),d.type="path",d.path=[],d.Path=o,B(d,e),b.canvas.appendChild(c);var f=F("skew");f.on=!0,c.appendChild(f),d.skew=f,d.transform(o);return d},a._engine.rect=function(b,c,d,e,f,g){var h=a._rectPath(c,d,e,f,g),i=b.path(h),j=i.attrs;i.X=j.x=c,i.Y=j.y=d,i.W=j.width=e,i.H=j.height=f,j.r=g,j.path=h,i.type="rect";return i},a._engine.ellipse=function(a,b,c,d,e){var f=a.path(),g=f.attrs;f.X=b-d,f.Y=c-e,f.W=d*2,f.H=e*2,f.type="ellipse",B(f,{cx:b,cy:c,rx:d,ry:e});return f},a._engine.circle=function(a,b,c,d){var e=a.path(),f=e.attrs;e.X=b-d,e.Y=c-d,e.W=e.H=d*2,e.type="circle",B(e,{cx:b,cy:c,r:d});return e},a._engine.image=function(b,c,d,e,f,g){var h=a._rectPath(d,e,f,g),i=b.path(h).attr({stroke:"none"}),k=i.attrs,l=i.node,m=l.getElementsByTagName(j)[0];k.src=c,i.X=k.x=d,i.Y=k.y=e,i.W=k.width=f,i.H=k.height=g,k.path=h,i.type="image",m.parentNode==l&&l.removeChild(m),m.rotate=!0,m.src=c,m.type="tile",i._.fillpos=[d,e],i._.fillsize=[f,g],l.appendChild(m),z(i,1,1,0,0,0);return i},a._engine.text=function(b,d,e,g){var h=F("shape"),i=F("path"),j=F("textpath");d=d||0,e=e||0,g=g||"",i.v=a.format("m{0},{1}l{2},{1}",f(d*u),f(e*u),f(d*u)+1),i.textpathok=!0,j.string=c(g),j.on=!0,h.style.cssText=t,h.coordsize=u+n+u,h.coordorigin="0 0";var k=new D(h,b),l={fill:"#000",stroke:"none",font:a._availableAttrs.font,text:g};k.shape=h,k.path=i,k.textpath=j,k.type="text",k.attrs.text=c(g),k.attrs.x=d,k.attrs.y=e,k.attrs.w=1,k.attrs.h=1,B(k,l),h.appendChild(j),h.appendChild(i),b.canvas.appendChild(h);var m=F("skew");m.on=!0,h.appendChild(m),k.skew=m,k.transform(o);return k},a._engine.setSize=function(b,c){var d=this.canvas.style;this.width=b,this.height=c,b==+b&&(b+="px"),c==+c&&(c+="px"),d.width=b,d.height=c,d.clip="rect(0 "+b+" "+c+" 0)",this._viewBox&&a._engine.setViewBox.apply(this,this._viewBox);return this},a._engine.setViewBox=function(b,c,d,e,f){a.eve("raphael.setViewBox",this,this._viewBox,[b,c,d,e,f]);var h=this.width,i=this.height,j=1/g(d/h,e/i),k,l;f&&(k=i/e,l=h/d,d*k<h&&(b-=(h-d*k)/2/k),e*l<i&&(c-=(i-e*l)/2/l)),this._viewBox=[b,c,d,e,!!f],this._viewBoxShift={dx:-b,dy:-c,scale:j},this.forEach(function(a){a.transform("...")});return this};var F;a._engine.initWin=function(a){var b=a.document;b.createStyleSheet().addRule(".rvml","behavior:url(#default#VML)");try{!b.namespaces.rvml&&b.namespaces.add("rvml","urn:schemas-microsoft-com:vml"),F=function(a){return b.createElement("<rvml:"+a+' class="rvml">')}}catch(c){F=function(a){return b.createElement("<"+a+' xmlns="urn:schemas-microsoft.com:vml" class="rvml">')}}},a._engine.initWin(a._g.win),a._engine.create=function(){var b=a._getContainer.apply(0,arguments),c=b.container,d=b.height,e,f=b.width,g=b.x,h=b.y;if(!c)throw new Error("VML container not found.");var i=new a._Paper,j=i.canvas=a._g.doc.createElement("div"),k=j.style;g=g||0,h=h||0,f=f||512,d=d||342,i.width=f,i.height=d,f==+f&&(f+="px"),d==+d&&(d+="px"),i.coordsize=u*1e3+n+u*1e3,i.coordorigin="0 0",i.span=a._g.doc.createElement("span"),i.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;",j.appendChild(i.span),k.cssText=a.format("top:0;left:0;width:{0};height:{1};display:inline-block;position:relative;clip:rect(0 {0} {1} 0);overflow:hidden",f,d),c==1?(a._g.doc.body.appendChild(j),k.left=g+"px",k.top=h+"px",k.position="absolute"):c.firstChild?c.insertBefore(j,c.firstChild):c.appendChild(j),i.renderfix=function(){};return i},a.prototype.clear=function(){a.eve("raphael.clear",this),this.canvas.innerHTML=o,this.span=a._g.doc.createElement("span"),this.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;",this.canvas.appendChild(this.span),this.bottom=this.top=null},a.prototype.remove=function(){a.eve("raphael.remove",this),this.canvas.parentNode.removeChild(this.canvas);for(var b in this)this[b]=typeof this[b]=="function"?a._removedFactory(b):null;return!0};var G=a.st;for(var H in E)E[b](H)&&!G[b](H)&&(G[H]=function(a){return function(){var b=arguments;return this.forEach(function(c){c[a].apply(c,b)})}}(H))}(window.Raphael)
|
1 |
+
!function t(e,r){"object"==typeof exports&&"object"==typeof module?module.exports=r():"function"==typeof define&&define.amd?define([],r):"object"==typeof exports?exports.Raphael=r():e.Raphael=r()}(this,function(){return function(t){function e(i){if(r[i])return r[i].exports;var n=r[i]={exports:{},id:i,loaded:!1};return t[i].call(n.exports,n,n.exports,e),n.loaded=!0,n.exports}var r={};return e.m=t,e.c=r,e.p="",e(0)}([function(t,e,r){var i,n;i=[r(1),r(3),r(4)],n=function(t){return t}.apply(e,i),!(void 0!==n&&(t.exports=n))},function(t,e,r){var i,n;i=[r(2)],n=function(t){function e(r){if(e.is(r,"function"))return w?r():t.on("raphael.DOMload",r);if(e.is(r,Q))return e._engine.create[z](e,r.splice(0,3+e.is(r[0],$))).add(r);var i=Array.prototype.slice.call(arguments,0);if(e.is(i[i.length-1],"function")){var n=i.pop();return w?n.call(e._engine.create[z](e,i)):t.on("raphael.DOMload",function(){n.call(e._engine.create[z](e,i))})}return e._engine.create[z](e,arguments)}function r(t){if("function"==typeof t||Object(t)!==t)return t;var e=new t.constructor;for(var i in t)t[A](i)&&(e[i]=r(t[i]));return e}function i(t,e){for(var r=0,i=t.length;r<i;r++)if(t[r]===e)return t.push(t.splice(r,1)[0])}function n(t,e,r){function n(){var a=Array.prototype.slice.call(arguments,0),s=a.join("␀"),o=n.cache=n.cache||{},l=n.count=n.count||[];return o[A](s)?(i(l,s),r?r(o[s]):o[s]):(l.length>=1e3&&delete o[l.shift()],l.push(s),o[s]=t[z](e,a),r?r(o[s]):o[s])}return n}function a(){return this.hex}function s(t,e){for(var r=[],i=0,n=t.length;n-2*!e>i;i+=2){var a=[{x:+t[i-2],y:+t[i-1]},{x:+t[i],y:+t[i+1]},{x:+t[i+2],y:+t[i+3]},{x:+t[i+4],y:+t[i+5]}];e?i?n-4==i?a[3]={x:+t[0],y:+t[1]}:n-2==i&&(a[2]={x:+t[0],y:+t[1]},a[3]={x:+t[2],y:+t[3]}):a[0]={x:+t[n-2],y:+t[n-1]}:n-4==i?a[3]=a[2]:i||(a[0]={x:+t[i],y:+t[i+1]}),r.push(["C",(-a[0].x+6*a[1].x+a[2].x)/6,(-a[0].y+6*a[1].y+a[2].y)/6,(a[1].x+6*a[2].x-a[3].x)/6,(a[1].y+6*a[2].y-a[3].y)/6,a[2].x,a[2].y])}return r}function o(t,e,r,i,n){var a=-3*e+9*r-9*i+3*n,s=t*a+6*e-12*r+6*i;return t*s-3*e+3*r}function l(t,e,r,i,n,a,s,l,h){null==h&&(h=1),h=h>1?1:h<0?0:h;for(var u=h/2,c=12,f=[-.1252,.1252,-.3678,.3678,-.5873,.5873,-.7699,.7699,-.9041,.9041,-.9816,.9816],p=[.2491,.2491,.2335,.2335,.2032,.2032,.1601,.1601,.1069,.1069,.0472,.0472],d=0,g=0;g<c;g++){var v=u*f[g]+u,x=o(v,t,r,n,s),y=o(v,e,i,a,l),m=x*x+y*y;d+=p[g]*Y.sqrt(m)}return u*d}function h(t,e,r,i,n,a,s,o,h){if(!(h<0||l(t,e,r,i,n,a,s,o)<h)){var u=1,c=u/2,f=u-c,p,d=.01;for(p=l(t,e,r,i,n,a,s,o,f);H(p-h)>d;)c/=2,f+=(p<h?1:-1)*c,p=l(t,e,r,i,n,a,s,o,f);return f}}function u(t,e,r,i,n,a,s,o){if(!(W(t,r)<G(n,s)||G(t,r)>W(n,s)||W(e,i)<G(a,o)||G(e,i)>W(a,o))){var l=(t*i-e*r)*(n-s)-(t-r)*(n*o-a*s),h=(t*i-e*r)*(a-o)-(e-i)*(n*o-a*s),u=(t-r)*(a-o)-(e-i)*(n-s);if(u){var c=l/u,f=h/u,p=+c.toFixed(2),d=+f.toFixed(2);if(!(p<+G(t,r).toFixed(2)||p>+W(t,r).toFixed(2)||p<+G(n,s).toFixed(2)||p>+W(n,s).toFixed(2)||d<+G(e,i).toFixed(2)||d>+W(e,i).toFixed(2)||d<+G(a,o).toFixed(2)||d>+W(a,o).toFixed(2)))return{x:c,y:f}}}}function c(t,e){return p(t,e)}function f(t,e){return p(t,e,1)}function p(t,r,i){var n=e.bezierBBox(t),a=e.bezierBBox(r);if(!e.isBBoxIntersect(n,a))return i?0:[];for(var s=l.apply(0,t),o=l.apply(0,r),h=W(~~(s/5),1),c=W(~~(o/5),1),f=[],p=[],d={},g=i?0:[],v=0;v<h+1;v++){var x=e.findDotsAtSegment.apply(e,t.concat(v/h));f.push({x:x.x,y:x.y,t:v/h})}for(v=0;v<c+1;v++)x=e.findDotsAtSegment.apply(e,r.concat(v/c)),p.push({x:x.x,y:x.y,t:v/c});for(v=0;v<h;v++)for(var y=0;y<c;y++){var m=f[v],b=f[v+1],_=p[y],w=p[y+1],k=H(b.x-m.x)<.001?"y":"x",B=H(w.x-_.x)<.001?"y":"x",C=u(m.x,m.y,b.x,b.y,_.x,_.y,w.x,w.y);if(C){if(d[C.x.toFixed(4)]==C.y.toFixed(4))continue;d[C.x.toFixed(4)]=C.y.toFixed(4);var S=m.t+H((C[k]-m[k])/(b[k]-m[k]))*(b.t-m.t),A=_.t+H((C[B]-_[B])/(w[B]-_[B]))*(w.t-_.t);S>=0&&S<=1.001&&A>=0&&A<=1.001&&(i?g++:g.push({x:C.x,y:C.y,t1:G(S,1),t2:G(A,1)}))}}return g}function d(t,r,i){t=e._path2curve(t),r=e._path2curve(r);for(var n,a,s,o,l,h,u,c,f,d,g=i?0:[],v=0,x=t.length;v<x;v++){var y=t[v];if("M"==y[0])n=l=y[1],a=h=y[2];else{"C"==y[0]?(f=[n,a].concat(y.slice(1)),n=f[6],a=f[7]):(f=[n,a,n,a,l,h,l,h],n=l,a=h);for(var m=0,b=r.length;m<b;m++){var _=r[m];if("M"==_[0])s=u=_[1],o=c=_[2];else{"C"==_[0]?(d=[s,o].concat(_.slice(1)),s=d[6],o=d[7]):(d=[s,o,s,o,u,c,u,c],s=u,o=c);var w=p(f,d,i);if(i)g+=w;else{for(var k=0,B=w.length;k<B;k++)w[k].segment1=v,w[k].segment2=m,w[k].bez1=f,w[k].bez2=d;g=g.concat(w)}}}}}return g}function g(t,e,r,i,n,a){null!=t?(this.a=+t,this.b=+e,this.c=+r,this.d=+i,this.e=+n,this.f=+a):(this.a=1,this.b=0,this.c=0,this.d=1,this.e=0,this.f=0)}function v(){return this.x+j+this.y}function x(){return this.x+j+this.y+j+this.width+" × "+this.height}function y(t,e,r,i,n,a){function s(t){return((c*t+u)*t+h)*t}function o(t,e){var r=l(t,e);return((d*r+p)*r+f)*r}function l(t,e){var r,i,n,a,o,l;for(n=t,l=0;l<8;l++){if(a=s(n)-t,H(a)<e)return n;if(o=(3*c*n+2*u)*n+h,H(o)<1e-6)break;n-=a/o}if(r=0,i=1,n=t,n<r)return r;if(n>i)return i;for(;r<i;){if(a=s(n),H(a-t)<e)return n;t>a?r=n:i=n,n=(i-r)/2+r}return n}var h=3*e,u=3*(i-e)-h,c=1-h-u,f=3*r,p=3*(n-r)-f,d=1-f-p;return o(t,1/(200*a))}function m(t,e){var r=[],i={};if(this.ms=e,this.times=1,t){for(var n in t)t[A](n)&&(i[ht(n)]=t[n],r.push(ht(n)));r.sort(Bt)}this.anim=i,this.top=r[r.length-1],this.percents=r}function b(r,i,n,a,s,o){n=ht(n);var l,h,u,c=[],f,p,d,v=r.ms,x={},m={},b={};if(a)for(w=0,B=Ee.length;w<B;w++){var _=Ee[w];if(_.el.id==i.id&&_.anim==r){_.percent!=n?(Ee.splice(w,1),u=1):h=_,i.attr(_.totalOrigin);break}}else a=+m;for(var w=0,B=r.percents.length;w<B;w++){if(r.percents[w]==n||r.percents[w]>a*r.top){n=r.percents[w],p=r.percents[w-1]||0,v=v/r.top*(n-p),f=r.percents[w+1],l=r.anim[n];break}a&&i.attr(r.anim[r.percents[w]])}if(l){if(h)h.initstatus=a,h.start=new Date-h.ms*a;else{for(var C in l)if(l[A](C)&&(pt[A](C)||i.paper.customAttributes[A](C)))switch(x[C]=i.attr(C),null==x[C]&&(x[C]=ft[C]),m[C]=l[C],pt[C]){case $:b[C]=(m[C]-x[C])/v;break;case"colour":x[C]=e.getRGB(x[C]);var S=e.getRGB(m[C]);b[C]={r:(S.r-x[C].r)/v,g:(S.g-x[C].g)/v,b:(S.b-x[C].b)/v};break;case"path":var T=Qt(x[C],m[C]),E=T[1];for(x[C]=T[0],b[C]=[],w=0,B=x[C].length;w<B;w++){b[C][w]=[0];for(var M=1,N=x[C][w].length;M<N;M++)b[C][w][M]=(E[w][M]-x[C][w][M])/v}break;case"transform":var L=i._,z=le(L[C],m[C]);if(z)for(x[C]=z.from,m[C]=z.to,b[C]=[],b[C].real=!0,w=0,B=x[C].length;w<B;w++)for(b[C][w]=[x[C][w][0]],M=1,N=x[C][w].length;M<N;M++)b[C][w][M]=(m[C][w][M]-x[C][w][M])/v;else{var F=i.matrix||new g,R={_:{transform:L.transform},getBBox:function(){return i.getBBox(1)}};x[C]=[F.a,F.b,F.c,F.d,F.e,F.f],se(R,m[C]),m[C]=R._.transform,b[C]=[(R.matrix.a-F.a)/v,(R.matrix.b-F.b)/v,(R.matrix.c-F.c)/v,(R.matrix.d-F.d)/v,(R.matrix.e-F.e)/v,(R.matrix.f-F.f)/v]}break;case"csv":var j=I(l[C])[q](k),D=I(x[C])[q](k);if("clip-rect"==C)for(x[C]=D,b[C]=[],w=D.length;w--;)b[C][w]=(j[w]-x[C][w])/v;m[C]=j;break;default:for(j=[][P](l[C]),D=[][P](x[C]),b[C]=[],w=i.paper.customAttributes[C].length;w--;)b[C][w]=((j[w]||0)-(D[w]||0))/v}var V=l.easing,O=e.easing_formulas[V];if(!O)if(O=I(V).match(st),O&&5==O.length){var Y=O;O=function(t){return y(t,+Y[1],+Y[2],+Y[3],+Y[4],v)}}else O=St;if(d=l.start||r.start||+new Date,_={anim:r,percent:n,timestamp:d,start:d+(r.del||0),status:0,initstatus:a||0,stop:!1,ms:v,easing:O,from:x,diff:b,to:m,el:i,callback:l.callback,prev:p,next:f,repeat:o||r.times,origin:i.attr(),totalOrigin:s},Ee.push(_),a&&!h&&!u&&(_.stop=!0,_.start=new Date-v*a,1==Ee.length))return Ne();u&&(_.start=new Date-_.ms*a),1==Ee.length&&Me(Ne)}t("raphael.anim.start."+i.id,i,r)}}function _(t){for(var e=0;e<Ee.length;e++)Ee[e].el.paper==t&&Ee.splice(e--,1)}e.version="2.2.0",e.eve=t;var w,k=/[, ]+/,B={circle:1,rect:1,path:1,ellipse:1,text:1,image:1},C=/\{(\d+)\}/g,S="prototype",A="hasOwnProperty",T={doc:document,win:window},E={was:Object.prototype[A].call(T.win,"Raphael"),is:T.win.Raphael},M=function(){this.ca=this.customAttributes={}},N,L="appendChild",z="apply",P="concat",F="ontouchstart"in T.win||T.win.DocumentTouch&&T.doc instanceof DocumentTouch,R="",j=" ",I=String,q="split",D="click dblclick mousedown mousemove mouseout mouseover mouseup touchstart touchmove touchend touchcancel"[q](j),V={mousedown:"touchstart",mousemove:"touchmove",mouseup:"touchend"},O=I.prototype.toLowerCase,Y=Math,W=Y.max,G=Y.min,H=Y.abs,X=Y.pow,U=Y.PI,$="number",Z="string",Q="array",J="toString",K="fill",tt=Object.prototype.toString,et={},rt="push",it=e._ISURL=/^url\(['"]?(.+?)['"]?\)$/i,nt=/^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgba?\(\s*([\d\.]+%?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+%?(?:\s*,\s*[\d\.]+%?)?)\s*\)|hsba?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\)|hsla?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\))\s*$/i,at={NaN:1,Infinity:1,"-Infinity":1},st=/^(?:cubic-)?bezier\(([^,]+),([^,]+),([^,]+),([^\)]+)\)/,ot=Y.round,lt="setAttribute",ht=parseFloat,ut=parseInt,ct=I.prototype.toUpperCase,ft=e._availableAttrs={"arrow-end":"none","arrow-start":"none",blur:0,"clip-rect":"0 0 1e9 1e9",cursor:"default",cx:0,cy:0,fill:"#fff","fill-opacity":1,font:'10px "Arial"',"font-family":'"Arial"',"font-size":"10","font-style":"normal","font-weight":400,gradient:0,height:0,href:"http://raphaeljs.com/","letter-spacing":0,opacity:1,path:"M0,0",r:0,rx:0,ry:0,src:"",stroke:"#000","stroke-dasharray":"","stroke-linecap":"butt","stroke-linejoin":"butt","stroke-miterlimit":0,"stroke-opacity":1,"stroke-width":1,target:"_blank","text-anchor":"middle",title:"Raphael",transform:"",width:0,x:0,y:0,"class":""},pt=e._availableAnimAttrs={blur:$,"clip-rect":"csv",cx:$,cy:$,fill:"colour","fill-opacity":$,"font-size":$,height:$,opacity:$,path:"path",r:$,rx:$,ry:$,stroke:"colour","stroke-opacity":$,"stroke-width":$,transform:"transform",width:$,x:$,y:$},dt=/[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]/g,gt=/[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*/,vt={hs:1,rg:1},xt=/,?([achlmqrstvxz]),?/gi,yt=/([achlmrqstvz])[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*)+)/gi,mt=/([rstm])[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*)+)/gi,bt=/(-?\d*\.?\d*(?:e[\-+]?\d+)?)[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*/gi,_t=e._radial_gradient=/^r(?:\(([^,]+?)[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*([^\)]+?)\))?/,wt={},kt=function(t,e){return t.key-e.key},Bt=function(t,e){return ht(t)-ht(e)},Ct=function(){},St=function(t){return t},At=e._rectPath=function(t,e,r,i,n){return n?[["M",t+n,e],["l",r-2*n,0],["a",n,n,0,0,1,n,n],["l",0,i-2*n],["a",n,n,0,0,1,-n,n],["l",2*n-r,0],["a",n,n,0,0,1,-n,-n],["l",0,2*n-i],["a",n,n,0,0,1,n,-n],["z"]]:[["M",t,e],["l",r,0],["l",0,i],["l",-r,0],["z"]]},Tt=function(t,e,r,i){return null==i&&(i=r),[["M",t,e],["m",0,-i],["a",r,i,0,1,1,0,2*i],["a",r,i,0,1,1,0,-2*i],["z"]]},Et=e._getPath={path:function(t){return t.attr("path")},circle:function(t){var e=t.attrs;return Tt(e.cx,e.cy,e.r)},ellipse:function(t){var e=t.attrs;return Tt(e.cx,e.cy,e.rx,e.ry)},rect:function(t){var e=t.attrs;return At(e.x,e.y,e.width,e.height,e.r)},image:function(t){var e=t.attrs;return At(e.x,e.y,e.width,e.height)},text:function(t){var e=t._getBBox();return At(e.x,e.y,e.width,e.height)},set:function(t){var e=t._getBBox();return At(e.x,e.y,e.width,e.height)}},Mt=e.mapPath=function(t,e){if(!e)return t;var r,i,n,a,s,o,l;for(t=Qt(t),n=0,s=t.length;n<s;n++)for(l=t[n],a=1,o=l.length;a<o;a+=2)r=e.x(l[a],l[a+1]),i=e.y(l[a],l[a+1]),l[a]=r,l[a+1]=i;return t};if(e._g=T,e.type=T.win.SVGAngle||T.doc.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1")?"SVG":"VML","VML"==e.type){var Nt=T.doc.createElement("div"),Lt;if(Nt.innerHTML='<v:shape adj="1"/>',Lt=Nt.firstChild,Lt.style.behavior="url(#default#VML)",!Lt||"object"!=typeof Lt.adj)return e.type=R;Nt=null}e.svg=!(e.vml="VML"==e.type),e._Paper=M,e.fn=N=M.prototype=e.prototype,e._id=0,e.is=function(t,e){return e=O.call(e),"finite"==e?!at[A](+t):"array"==e?t instanceof Array:"null"==e&&null===t||e==typeof t&&null!==t||"object"==e&&t===Object(t)||"array"==e&&Array.isArray&&Array.isArray(t)||tt.call(t).slice(8,-1).toLowerCase()==e},e.angle=function(t,r,i,n,a,s){if(null==a){var o=t-i,l=r-n;return o||l?(180+180*Y.atan2(-l,-o)/U+360)%360:0}return e.angle(t,r,a,s)-e.angle(i,n,a,s)},e.rad=function(t){return t%360*U/180},e.deg=function(t){return Math.round(180*t/U%360*1e3)/1e3},e.snapTo=function(t,r,i){if(i=e.is(i,"finite")?i:10,e.is(t,Q)){for(var n=t.length;n--;)if(H(t[n]-r)<=i)return t[n]}else{t=+t;var a=r%t;if(a<i)return r-a;if(a>t-i)return r-a+t}return r};var zt=e.createUUID=function(t,e){return function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(t,e).toUpperCase()}}(/[xy]/g,function(t){var e=16*Y.random()|0,r="x"==t?e:3&e|8;return r.toString(16)});e.setWindow=function(r){t("raphael.setWindow",e,T.win,r),T.win=r,T.doc=T.win.document,e._engine.initWin&&e._engine.initWin(T.win)};var Pt=function(t){if(e.vml){var r=/^\s+|\s+$/g,i;try{var a=new ActiveXObject("htmlfile");a.write("<body>"),a.close(),i=a.body}catch(s){i=createPopup().document.body}var o=i.createTextRange();Pt=n(function(t){try{i.style.color=I(t).replace(r,R);var e=o.queryCommandValue("ForeColor");return e=(255&e)<<16|65280&e|(16711680&e)>>>16,"#"+("000000"+e.toString(16)).slice(-6)}catch(n){return"none"}})}else{var l=T.doc.createElement("i");l.title="Raphaël Colour Picker",l.style.display="none",T.doc.body.appendChild(l),Pt=n(function(t){return l.style.color=t,T.doc.defaultView.getComputedStyle(l,R).getPropertyValue("color")})}return Pt(t)},Ft=function(){return"hsb("+[this.h,this.s,this.b]+")"},Rt=function(){return"hsl("+[this.h,this.s,this.l]+")"},jt=function(){return this.hex},It=function(t,r,i){if(null==r&&e.is(t,"object")&&"r"in t&&"g"in t&&"b"in t&&(i=t.b,r=t.g,t=t.r),null==r&&e.is(t,Z)){var n=e.getRGB(t);t=n.r,r=n.g,i=n.b}return(t>1||r>1||i>1)&&(t/=255,r/=255,i/=255),[t,r,i]},qt=function(t,r,i,n){t*=255,r*=255,i*=255;var a={r:t,g:r,b:i,hex:e.rgb(t,r,i),toString:jt};return e.is(n,"finite")&&(a.opacity=n),a};e.color=function(t){var r;return e.is(t,"object")&&"h"in t&&"s"in t&&"b"in t?(r=e.hsb2rgb(t),t.r=r.r,t.g=r.g,t.b=r.b,t.hex=r.hex):e.is(t,"object")&&"h"in t&&"s"in t&&"l"in t?(r=e.hsl2rgb(t),t.r=r.r,t.g=r.g,t.b=r.b,t.hex=r.hex):(e.is(t,"string")&&(t=e.getRGB(t)),e.is(t,"object")&&"r"in t&&"g"in t&&"b"in t?(r=e.rgb2hsl(t),t.h=r.h,t.s=r.s,t.l=r.l,r=e.rgb2hsb(t),t.v=r.b):(t={hex:"none"},t.r=t.g=t.b=t.h=t.s=t.v=t.l=-1)),t.toString=jt,t},e.hsb2rgb=function(t,e,r,i){this.is(t,"object")&&"h"in t&&"s"in t&&"b"in t&&(r=t.b,e=t.s,i=t.o,t=t.h),t*=360;var n,a,s,o,l;return t=t%360/60,l=r*e,o=l*(1-H(t%2-1)),n=a=s=r-l,t=~~t,n+=[l,o,0,0,o,l][t],a+=[o,l,l,o,0,0][t],s+=[0,0,o,l,l,o][t],qt(n,a,s,i)},e.hsl2rgb=function(t,e,r,i){this.is(t,"object")&&"h"in t&&"s"in t&&"l"in t&&(r=t.l,e=t.s,t=t.h),(t>1||e>1||r>1)&&(t/=360,e/=100,r/=100),t*=360;var n,a,s,o,l;return t=t%360/60,l=2*e*(r<.5?r:1-r),o=l*(1-H(t%2-1)),n=a=s=r-l/2,t=~~t,n+=[l,o,0,0,o,l][t],a+=[o,l,l,o,0,0][t],s+=[0,0,o,l,l,o][t],qt(n,a,s,i)},e.rgb2hsb=function(t,e,r){r=It(t,e,r),t=r[0],e=r[1],r=r[2];var i,n,a,s;return a=W(t,e,r),s=a-G(t,e,r),i=0==s?null:a==t?(e-r)/s:a==e?(r-t)/s+2:(t-e)/s+4,i=(i+360)%6*60/360,n=0==s?0:s/a,{h:i,s:n,b:a,toString:Ft}},e.rgb2hsl=function(t,e,r){r=It(t,e,r),t=r[0],e=r[1],r=r[2];var i,n,a,s,o,l;return s=W(t,e,r),o=G(t,e,r),l=s-o,i=0==l?null:s==t?(e-r)/l:s==e?(r-t)/l+2:(t-e)/l+4,i=(i+360)%6*60/360,a=(s+o)/2,n=0==l?0:a<.5?l/(2*a):l/(2-2*a),{h:i,s:n,l:a,toString:Rt}},e._path2string=function(){return this.join(",").replace(xt,"$1")};var Dt=e._preload=function(t,e){var r=T.doc.createElement("img");r.style.cssText="position:absolute;left:-9999em;top:-9999em",r.onload=function(){e.call(this),this.onload=null,T.doc.body.removeChild(this)},r.onerror=function(){T.doc.body.removeChild(this)},T.doc.body.appendChild(r),r.src=t};e.getRGB=n(function(t){if(!t||(t=I(t)).indexOf("-")+1)return{r:-1,g:-1,b:-1,hex:"none",error:1,toString:a};if("none"==t)return{r:-1,g:-1,b:-1,hex:"none",toString:a};!(vt[A](t.toLowerCase().substring(0,2))||"#"==t.charAt())&&(t=Pt(t));var r,i,n,s,o,l,h,u=t.match(nt);return u?(u[2]&&(s=ut(u[2].substring(5),16),n=ut(u[2].substring(3,5),16),i=ut(u[2].substring(1,3),16)),u[3]&&(s=ut((l=u[3].charAt(3))+l,16),n=ut((l=u[3].charAt(2))+l,16),i=ut((l=u[3].charAt(1))+l,16)),u[4]&&(h=u[4][q](gt),i=ht(h[0]),"%"==h[0].slice(-1)&&(i*=2.55),n=ht(h[1]),"%"==h[1].slice(-1)&&(n*=2.55),s=ht(h[2]),"%"==h[2].slice(-1)&&(s*=2.55),"rgba"==u[1].toLowerCase().slice(0,4)&&(o=ht(h[3])),h[3]&&"%"==h[3].slice(-1)&&(o/=100)),u[5]?(h=u[5][q](gt),i=ht(h[0]),"%"==h[0].slice(-1)&&(i*=2.55),n=ht(h[1]),"%"==h[1].slice(-1)&&(n*=2.55),s=ht(h[2]),"%"==h[2].slice(-1)&&(s*=2.55),("deg"==h[0].slice(-3)||"°"==h[0].slice(-1))&&(i/=360),"hsba"==u[1].toLowerCase().slice(0,4)&&(o=ht(h[3])),h[3]&&"%"==h[3].slice(-1)&&(o/=100),e.hsb2rgb(i,n,s,o)):u[6]?(h=u[6][q](gt),i=ht(h[0]),"%"==h[0].slice(-1)&&(i*=2.55),n=ht(h[1]),"%"==h[1].slice(-1)&&(n*=2.55),s=ht(h[2]),"%"==h[2].slice(-1)&&(s*=2.55),("deg"==h[0].slice(-3)||"°"==h[0].slice(-1))&&(i/=360),"hsla"==u[1].toLowerCase().slice(0,4)&&(o=ht(h[3])),h[3]&&"%"==h[3].slice(-1)&&(o/=100),e.hsl2rgb(i,n,s,o)):(u={r:i,g:n,b:s,toString:a},u.hex="#"+(16777216|s|n<<8|i<<16).toString(16).slice(1),e.is(o,"finite")&&(u.opacity=o),u)):{r:-1,g:-1,b:-1,hex:"none",error:1,toString:a}},e),e.hsb=n(function(t,r,i){return e.hsb2rgb(t,r,i).hex}),e.hsl=n(function(t,r,i){return e.hsl2rgb(t,r,i).hex}),e.rgb=n(function(t,e,r){function i(t){return t+.5|0}return"#"+(16777216|i(r)|i(e)<<8|i(t)<<16).toString(16).slice(1)}),e.getColor=function(t){var e=this.getColor.start=this.getColor.start||{h:0,s:1,b:t||.75},r=this.hsb2rgb(e.h,e.s,e.b);return e.h+=.075,e.h>1&&(e.h=0,e.s-=.2,e.s<=0&&(this.getColor.start={h:0,s:1,b:e.b})),r.hex},e.getColor.reset=function(){delete this.start},e.parsePathString=function(t){if(!t)return null;var r=Vt(t);if(r.arr)return Yt(r.arr);var i={a:7,c:6,h:1,l:2,m:2,r:4,q:4,s:4,t:2,v:1,z:0},n=[];return e.is(t,Q)&&e.is(t[0],Q)&&(n=Yt(t)),n.length||I(t).replace(yt,function(t,e,r){var a=[],s=e.toLowerCase();if(r.replace(bt,function(t,e){e&&a.push(+e)}),"m"==s&&a.length>2&&(n.push([e][P](a.splice(0,2))),s="l",e="m"==e?"l":"L"),"r"==s)n.push([e][P](a));else for(;a.length>=i[s]&&(n.push([e][P](a.splice(0,i[s]))),i[s]););}),n.toString=e._path2string,r.arr=Yt(n),n},e.parseTransformString=n(function(t){if(!t)return null;var r={r:3,s:4,t:2,m:6},i=[];return e.is(t,Q)&&e.is(t[0],Q)&&(i=Yt(t)),i.length||I(t).replace(mt,function(t,e,r){var n=[],a=O.call(e);r.replace(bt,function(t,e){e&&n.push(+e)}),i.push([e][P](n))}),i.toString=e._path2string,i});var Vt=function(t){var e=Vt.ps=Vt.ps||{};return e[t]?e[t].sleep=100:e[t]={sleep:100},setTimeout(function(){for(var r in e)e[A](r)&&r!=t&&(e[r].sleep--,!e[r].sleep&&delete e[r])}),e[t]};e.findDotsAtSegment=function(t,e,r,i,n,a,s,o,l){var h=1-l,u=X(h,3),c=X(h,2),f=l*l,p=f*l,d=u*t+3*c*l*r+3*h*l*l*n+p*s,g=u*e+3*c*l*i+3*h*l*l*a+p*o,v=t+2*l*(r-t)+f*(n-2*r+t),x=e+2*l*(i-e)+f*(a-2*i+e),y=r+2*l*(n-r)+f*(s-2*n+r),m=i+2*l*(a-i)+f*(o-2*a+i),b=h*t+l*r,_=h*e+l*i,w=h*n+l*s,k=h*a+l*o,B=90-180*Y.atan2(v-y,x-m)/U;return(v>y||x<m)&&(B+=180),{x:d,y:g,m:{x:v,y:x},n:{x:y,y:m},start:{x:b,y:_},end:{x:w,y:k},alpha:B}},e.bezierBBox=function(t,r,i,n,a,s,o,l){e.is(t,"array")||(t=[t,r,i,n,a,s,o,l]);var h=Zt.apply(null,t);return{x:h.min.x,y:h.min.y,x2:h.max.x,y2:h.max.y,width:h.max.x-h.min.x,height:h.max.y-h.min.y}},e.isPointInsideBBox=function(t,e,r){return e>=t.x&&e<=t.x2&&r>=t.y&&r<=t.y2},e.isBBoxIntersect=function(t,r){var i=e.isPointInsideBBox;return i(r,t.x,t.y)||i(r,t.x2,t.y)||i(r,t.x,t.y2)||i(r,t.x2,t.y2)||i(t,r.x,r.y)||i(t,r.x2,r.y)||i(t,r.x,r.y2)||i(t,r.x2,r.y2)||(t.x<r.x2&&t.x>r.x||r.x<t.x2&&r.x>t.x)&&(t.y<r.y2&&t.y>r.y||r.y<t.y2&&r.y>t.y)},e.pathIntersection=function(t,e){return d(t,e)},e.pathIntersectionNumber=function(t,e){return d(t,e,1)},e.isPointInsidePath=function(t,r,i){var n=e.pathBBox(t);return e.isPointInsideBBox(n,r,i)&&d(t,[["M",r,i],["H",n.x2+10]],1)%2==1},e._removedFactory=function(e){return function(){t("raphael.log",null,"Raphaël: you are calling to method “"+e+"” of removed object",e)}};var Ot=e.pathBBox=function(t){var e=Vt(t);if(e.bbox)return r(e.bbox);if(!t)return{x:0,y:0,width:0,height:0,x2:0,y2:0};t=Qt(t);for(var i=0,n=0,a=[],s=[],o,l=0,h=t.length;l<h;l++)if(o=t[l],"M"==o[0])i=o[1],n=o[2],a.push(i),s.push(n);else{var u=Zt(i,n,o[1],o[2],o[3],o[4],o[5],o[6]);a=a[P](u.min.x,u.max.x),s=s[P](u.min.y,u.max.y),i=o[5],n=o[6]}var c=G[z](0,a),f=G[z](0,s),p=W[z](0,a),d=W[z](0,s),g=p-c,v=d-f,x={x:c,y:f,x2:p,y2:d,width:g,height:v,cx:c+g/2,cy:f+v/2};return e.bbox=r(x),x},Yt=function(t){var i=r(t);return i.toString=e._path2string,i},Wt=e._pathToRelative=function(t){var r=Vt(t);if(r.rel)return Yt(r.rel);e.is(t,Q)&&e.is(t&&t[0],Q)||(t=e.parsePathString(t));var i=[],n=0,a=0,s=0,o=0,l=0;"M"==t[0][0]&&(n=t[0][1],a=t[0][2],s=n,o=a,l++,i.push(["M",n,a]));for(var h=l,u=t.length;h<u;h++){var c=i[h]=[],f=t[h];if(f[0]!=O.call(f[0]))switch(c[0]=O.call(f[0]),c[0]){case"a":c[1]=f[1],c[2]=f[2],c[3]=f[3],c[4]=f[4],c[5]=f[5],c[6]=+(f[6]-n).toFixed(3),c[7]=+(f[7]-a).toFixed(3);break;case"v":c[1]=+(f[1]-a).toFixed(3);break;case"m":s=f[1],o=f[2];default:for(var p=1,d=f.length;p<d;p++)c[p]=+(f[p]-(p%2?n:a)).toFixed(3)}else{c=i[h]=[],"m"==f[0]&&(s=f[1]+n,o=f[2]+a);for(var g=0,v=f.length;g<v;g++)i[h][g]=f[g]}var x=i[h].length;switch(i[h][0]){case"z":n=s,a=o;break;case"h":n+=+i[h][x-1];break;case"v":a+=+i[h][x-1];break;default:n+=+i[h][x-2],a+=+i[h][x-1]}}return i.toString=e._path2string,r.rel=Yt(i),i},Gt=e._pathToAbsolute=function(t){var r=Vt(t);if(r.abs)return Yt(r.abs);if(e.is(t,Q)&&e.is(t&&t[0],Q)||(t=e.parsePathString(t)),!t||!t.length)return[["M",0,0]];var i=[],n=0,a=0,o=0,l=0,h=0;"M"==t[0][0]&&(n=+t[0][1],a=+t[0][2],o=n,l=a,h++,i[0]=["M",n,a]);for(var u=3==t.length&&"M"==t[0][0]&&"R"==t[1][0].toUpperCase()&&"Z"==t[2][0].toUpperCase(),c,f,p=h,d=t.length;p<d;p++){if(i.push(c=[]),f=t[p],f[0]!=ct.call(f[0]))switch(c[0]=ct.call(f[0]),c[0]){case"A":c[1]=f[1],c[2]=f[2],c[3]=f[3],c[4]=f[4],c[5]=f[5],c[6]=+(f[6]+n),c[7]=+(f[7]+a);break;case"V":c[1]=+f[1]+a;break;case"H":c[1]=+f[1]+n;break;case"R":for(var g=[n,a][P](f.slice(1)),v=2,x=g.length;v<x;v++)g[v]=+g[v]+n,g[++v]=+g[v]+a;i.pop(),i=i[P](s(g,u));break;case"M":o=+f[1]+n,l=+f[2]+a;default:for(v=1,x=f.length;v<x;v++)c[v]=+f[v]+(v%2?n:a)}else if("R"==f[0])g=[n,a][P](f.slice(1)),i.pop(),i=i[P](s(g,u)),c=["R"][P](f.slice(-2));else for(var y=0,m=f.length;y<m;y++)c[y]=f[y];switch(c[0]){case"Z":n=o,a=l;break;case"H":n=c[1];break;case"V":a=c[1];break;case"M":o=c[c.length-2],l=c[c.length-1];default:n=c[c.length-2],a=c[c.length-1]}}return i.toString=e._path2string,r.abs=Yt(i),i},Ht=function(t,e,r,i){return[t,e,r,i,r,i]},Xt=function(t,e,r,i,n,a){var s=1/3,o=2/3;return[s*t+o*r,s*e+o*i,s*n+o*r,s*a+o*i,n,a]},Ut=function(t,e,r,i,a,s,o,l,h,u){var c=120*U/180,f=U/180*(+a||0),p=[],d,g=n(function(t,e,r){var i=t*Y.cos(r)-e*Y.sin(r),n=t*Y.sin(r)+e*Y.cos(r);return{x:i,y:n}});if(u)S=u[0],A=u[1],B=u[2],C=u[3];else{d=g(t,e,-f),t=d.x,e=d.y,d=g(l,h,-f),l=d.x,h=d.y;var v=Y.cos(U/180*a),x=Y.sin(U/180*a),y=(t-l)/2,m=(e-h)/2,b=y*y/(r*r)+m*m/(i*i);b>1&&(b=Y.sqrt(b),r=b*r,i=b*i);var _=r*r,w=i*i,k=(s==o?-1:1)*Y.sqrt(H((_*w-_*m*m-w*y*y)/(_*m*m+w*y*y))),B=k*r*m/i+(t+l)/2,C=k*-i*y/r+(e+h)/2,S=Y.asin(((e-C)/i).toFixed(9)),A=Y.asin(((h-C)/i).toFixed(9));S=t<B?U-S:S,A=l<B?U-A:A,S<0&&(S=2*U+S),A<0&&(A=2*U+A),o&&S>A&&(S-=2*U),!o&&A>S&&(A-=2*U)}var T=A-S;if(H(T)>c){var E=A,M=l,N=h;A=S+c*(o&&A>S?1:-1),l=B+r*Y.cos(A),h=C+i*Y.sin(A),p=Ut(l,h,r,i,a,0,o,M,N,[A,E,B,C])}T=A-S;var L=Y.cos(S),z=Y.sin(S),F=Y.cos(A),R=Y.sin(A),j=Y.tan(T/4),I=4/3*r*j,D=4/3*i*j,V=[t,e],O=[t+I*z,e-D*L],W=[l+I*R,h-D*F],G=[l,h];if(O[0]=2*V[0]-O[0],O[1]=2*V[1]-O[1],u)return[O,W,G][P](p);p=[O,W,G][P](p).join()[q](",");for(var X=[],$=0,Z=p.length;$<Z;$++)X[$]=$%2?g(p[$-1],p[$],f).y:g(p[$],p[$+1],f).x;return X},$t=function(t,e,r,i,n,a,s,o,l){var h=1-l;return{x:X(h,3)*t+3*X(h,2)*l*r+3*h*l*l*n+X(l,3)*s,y:X(h,3)*e+3*X(h,2)*l*i+3*h*l*l*a+X(l,3)*o}},Zt=n(function(t,e,r,i,n,a,s,o){var l=n-2*r+t-(s-2*n+r),h=2*(r-t)-2*(n-r),u=t-r,c=(-h+Y.sqrt(h*h-4*l*u))/2/l,f=(-h-Y.sqrt(h*h-4*l*u))/2/l,p=[e,o],d=[t,s],g;return H(c)>"1e12"&&(c=.5),H(f)>"1e12"&&(f=.5),c>0&&c<1&&(g=$t(t,e,r,i,n,a,s,o,c),d.push(g.x),p.push(g.y)),f>0&&f<1&&(g=$t(t,e,r,i,n,a,s,o,f),d.push(g.x),p.push(g.y)),l=a-2*i+e-(o-2*a+i),h=2*(i-e)-2*(a-i),u=e-i,c=(-h+Y.sqrt(h*h-4*l*u))/2/l,f=(-h-Y.sqrt(h*h-4*l*u))/2/l,H(c)>"1e12"&&(c=.5),H(f)>"1e12"&&(f=.5),c>0&&c<1&&(g=$t(t,e,r,i,n,a,s,o,c),d.push(g.x),p.push(g.y)),f>0&&f<1&&(g=$t(t,e,r,i,n,a,s,o,f),d.push(g.x),p.push(g.y)),{min:{x:G[z](0,d),y:G[z](0,p)},max:{x:W[z](0,d),y:W[z](0,p)}}}),Qt=e._path2curve=n(function(t,e){var r=!e&&Vt(t);if(!e&&r.curve)return Yt(r.curve);for(var i=Gt(t),n=e&&Gt(e),a={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},s={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},o=(function(t,e,r){var i,n,a={T:1,Q:1};if(!t)return["C",e.x,e.y,e.x,e.y,e.x,e.y];switch(!(t[0]in a)&&(e.qx=e.qy=null),t[0]){case"M":e.X=t[1],e.Y=t[2];break;case"A":t=["C"][P](Ut[z](0,[e.x,e.y][P](t.slice(1))));break;case"S":"C"==r||"S"==r?(i=2*e.x-e.bx,n=2*e.y-e.by):(i=e.x,n=e.y),t=["C",i,n][P](t.slice(1));break;case"T":"Q"==r||"T"==r?(e.qx=2*e.x-e.qx,e.qy=2*e.y-e.qy):(e.qx=e.x,e.qy=e.y),t=["C"][P](Xt(e.x,e.y,e.qx,e.qy,t[1],t[2]));break;case"Q":e.qx=t[1],e.qy=t[2],t=["C"][P](Xt(e.x,e.y,t[1],t[2],t[3],t[4]));break;case"L":t=["C"][P](Ht(e.x,e.y,t[1],t[2]));break;case"H":t=["C"][P](Ht(e.x,e.y,t[1],e.y));break;case"V":t=["C"][P](Ht(e.x,e.y,e.x,t[1]));break;case"Z":t=["C"][P](Ht(e.x,e.y,e.X,e.Y))}return t}),l=function(t,e){if(t[e].length>7){t[e].shift();for(var r=t[e];r.length;)u[e]="A",n&&(c[e]="A"),t.splice(e++,0,["C"][P](r.splice(0,6)));t.splice(e,1),g=W(i.length,n&&n.length||0)}},h=function(t,e,r,a,s){t&&e&&"M"==t[s][0]&&"M"!=e[s][0]&&(e.splice(s,0,["M",a.x,a.y]),r.bx=0,r.by=0,r.x=t[s][1],r.y=t[s][2],g=W(i.length,n&&n.length||0))},u=[],c=[],f="",p="",d=0,g=W(i.length,n&&n.length||0);d<g;d++){i[d]&&(f=i[d][0]),"C"!=f&&(u[d]=f,d&&(p=u[d-1])),i[d]=o(i[d],a,p),"A"!=u[d]&&"C"==f&&(u[d]="C"),l(i,d),n&&(n[d]&&(f=n[d][0]),"C"!=f&&(c[d]=f,d&&(p=c[d-1])),n[d]=o(n[d],s,p),"A"!=c[d]&&"C"==f&&(c[d]="C"),l(n,d)),h(i,n,a,s,d),h(n,i,s,a,d);var v=i[d],x=n&&n[d],y=v.length,m=n&&x.length;a.x=v[y-2],a.y=v[y-1],a.bx=ht(v[y-4])||a.x,a.by=ht(v[y-3])||a.y,s.bx=n&&(ht(x[m-4])||s.x),s.by=n&&(ht(x[m-3])||s.y),s.x=n&&x[m-2],s.y=n&&x[m-1]}return n||(r.curve=Yt(i)),n?[i,n]:i},null,Yt),Jt=e._parseDots=n(function(t){for(var r=[],i=0,n=t.length;i<n;i++){var a={},s=t[i].match(/^([^:]*):?([\d\.]*)/);if(a.color=e.getRGB(s[1]),a.color.error)return null;a.opacity=a.color.opacity,a.color=a.color.hex,s[2]&&(a.offset=s[2]+"%"),r.push(a)}for(i=1,n=r.length-1;i<n;i++)if(!r[i].offset){for(var o=ht(r[i-1].offset||0),l=0,h=i+1;h<n;h++)if(r[h].offset){l=r[h].offset;break}l||(l=100,h=n),l=ht(l);for(var u=(l-o)/(h-i+1);i<h;i++)o+=u,r[i].offset=o+"%"}return r}),Kt=e._tear=function(t,e){t==e.top&&(e.top=t.prev),t==e.bottom&&(e.bottom=t.next),t.next&&(t.next.prev=t.prev),t.prev&&(t.prev.next=t.next)},te=e._tofront=function(t,e){e.top!==t&&(Kt(t,e),t.next=null,t.prev=e.top,e.top.next=t,e.top=t)},ee=e._toback=function(t,e){e.bottom!==t&&(Kt(t,e),t.next=e.bottom,t.prev=null,e.bottom.prev=t,e.bottom=t)},re=e._insertafter=function(t,e,r){Kt(t,r),e==r.top&&(r.top=t),e.next&&(e.next.prev=t),t.next=e.next,t.prev=e,e.next=t},ie=e._insertbefore=function(t,e,r){Kt(t,r),e==r.bottom&&(r.bottom=t),e.prev&&(e.prev.next=t),t.prev=e.prev,e.prev=t,t.next=e},ne=e.toMatrix=function(t,e){var r=Ot(t),i={_:{transform:R},getBBox:function(){return r}};return se(i,e),i.matrix},ae=e.transformPath=function(t,e){return Mt(t,ne(t,e))},se=e._extractTransform=function(t,r){if(null==r)return t._.transform;r=I(r).replace(/\.{3}|\u2026/g,t._.transform||R);var i=e.parseTransformString(r),n=0,a=0,s=0,o=1,l=1,h=t._,u=new g;if(h.transform=i||[],i)for(var c=0,f=i.length;c<f;c++){var p=i[c],d=p.length,v=I(p[0]).toLowerCase(),x=p[0]!=v,y=x?u.invert():0,m,b,_,w,k;"t"==v&&3==d?x?(m=y.x(0,0),b=y.y(0,0),_=y.x(p[1],p[2]),w=y.y(p[1],p[2]),u.translate(_-m,w-b)):u.translate(p[1],p[2]):"r"==v?2==d?(k=k||t.getBBox(1),u.rotate(p[1],k.x+k.width/2,k.y+k.height/2),n+=p[1]):4==d&&(x?(_=y.x(p[2],p[3]),w=y.y(p[2],p[3]),u.rotate(p[1],_,w)):u.rotate(p[1],p[2],p[3]),n+=p[1]):"s"==v?2==d||3==d?(k=k||t.getBBox(1),u.scale(p[1],p[d-1],k.x+k.width/2,k.y+k.height/2),o*=p[1],l*=p[d-1]):5==d&&(x?(_=y.x(p[3],p[4]),w=y.y(p[3],p[4]),u.scale(p[1],p[2],_,w)):u.scale(p[1],p[2],p[3],p[4]),o*=p[1],l*=p[2]):"m"==v&&7==d&&u.add(p[1],p[2],p[3],p[4],p[5],p[6]),h.dirtyT=1,t.matrix=u}t.matrix=u,h.sx=o,h.sy=l,h.deg=n,h.dx=a=u.e,h.dy=s=u.f,1==o&&1==l&&!n&&h.bbox?(h.bbox.x+=+a,h.bbox.y+=+s):h.dirtyT=1},oe=function(t){var e=t[0];switch(e.toLowerCase()){case"t":return[e,0,0];case"m":return[e,1,0,0,1,0,0];case"r":return 4==t.length?[e,0,t[2],t[3]]:[e,0];case"s":return 5==t.length?[e,1,1,t[3],t[4]]:3==t.length?[e,1,1]:[e,1]}},le=e._equaliseTransform=function(t,r){r=I(r).replace(/\.{3}|\u2026/g,t),t=e.parseTransformString(t)||[],r=e.parseTransformString(r)||[];for(var i=W(t.length,r.length),n=[],a=[],s=0,o,l,h,u;s<i;s++){if(h=t[s]||oe(r[s]),u=r[s]||oe(h),h[0]!=u[0]||"r"==h[0].toLowerCase()&&(h[2]!=u[2]||h[3]!=u[3])||"s"==h[0].toLowerCase()&&(h[3]!=u[3]||h[4]!=u[4]))return;for(n[s]=[],a[s]=[],o=0,l=W(h.length,u.length);o<l;o++)o in h&&(n[s][o]=h[o]),o in u&&(a[s][o]=u[o])}return{from:n,to:a}};e._getContainer=function(t,r,i,n){var a;if(a=null!=n||e.is(t,"object")?t:T.doc.getElementById(t),null!=a)return a.tagName?null==r?{container:a,width:a.style.pixelWidth||a.offsetWidth,height:a.style.pixelHeight||a.offsetHeight}:{container:a,width:r,height:i}:{container:1,x:t,y:r,width:i,height:n}},e.pathToRelative=Wt,e._engine={},e.path2curve=Qt,e.matrix=function(t,e,r,i,n,a){return new g(t,e,r,i,n,a)},function(t){function r(t){return t[0]*t[0]+t[1]*t[1]}function i(t){var e=Y.sqrt(r(t));t[0]&&(t[0]/=e),t[1]&&(t[1]/=e)}t.add=function(t,e,r,i,n,a){var s=[[],[],[]],o=[[this.a,this.c,this.e],[this.b,this.d,this.f],[0,0,1]],l=[[t,r,n],[e,i,a],[0,0,1]],h,u,c,f;for(t&&t instanceof g&&(l=[[t.a,t.c,t.e],[t.b,t.d,t.f],[0,0,1]]),h=0;h<3;h++)for(u=0;u<3;u++){for(f=0,c=0;c<3;c++)f+=o[h][c]*l[c][u];s[h][u]=f}this.a=s[0][0],this.b=s[1][0],this.c=s[0][1],this.d=s[1][1],this.e=s[0][2],this.f=s[1][2]},t.invert=function(){var t=this,e=t.a*t.d-t.b*t.c;return new g(t.d/e,-t.b/e,-t.c/e,t.a/e,(t.c*t.f-t.d*t.e)/e,(t.b*t.e-t.a*t.f)/e)},t.clone=function(){return new g(this.a,this.b,this.c,this.d,this.e,this.f)},t.translate=function(t,e){
|
2 |
+
this.add(1,0,0,1,t,e)},t.scale=function(t,e,r,i){null==e&&(e=t),(r||i)&&this.add(1,0,0,1,r,i),this.add(t,0,0,e,0,0),(r||i)&&this.add(1,0,0,1,-r,-i)},t.rotate=function(t,r,i){t=e.rad(t),r=r||0,i=i||0;var n=+Y.cos(t).toFixed(9),a=+Y.sin(t).toFixed(9);this.add(n,a,-a,n,r,i),this.add(1,0,0,1,-r,-i)},t.x=function(t,e){return t*this.a+e*this.c+this.e},t.y=function(t,e){return t*this.b+e*this.d+this.f},t.get=function(t){return+this[I.fromCharCode(97+t)].toFixed(4)},t.toString=function(){return e.svg?"matrix("+[this.get(0),this.get(1),this.get(2),this.get(3),this.get(4),this.get(5)].join()+")":[this.get(0),this.get(2),this.get(1),this.get(3),0,0].join()},t.toFilter=function(){return"progid:DXImageTransform.Microsoft.Matrix(M11="+this.get(0)+", M12="+this.get(2)+", M21="+this.get(1)+", M22="+this.get(3)+", Dx="+this.get(4)+", Dy="+this.get(5)+", sizingmethod='auto expand')"},t.offset=function(){return[this.e.toFixed(4),this.f.toFixed(4)]},t.split=function(){var t={};t.dx=this.e,t.dy=this.f;var n=[[this.a,this.c],[this.b,this.d]];t.scalex=Y.sqrt(r(n[0])),i(n[0]),t.shear=n[0][0]*n[1][0]+n[0][1]*n[1][1],n[1]=[n[1][0]-n[0][0]*t.shear,n[1][1]-n[0][1]*t.shear],t.scaley=Y.sqrt(r(n[1])),i(n[1]),t.shear/=t.scaley;var a=-n[0][1],s=n[1][1];return s<0?(t.rotate=e.deg(Y.acos(s)),a<0&&(t.rotate=360-t.rotate)):t.rotate=e.deg(Y.asin(a)),t.isSimple=!(+t.shear.toFixed(9)||t.scalex.toFixed(9)!=t.scaley.toFixed(9)&&t.rotate),t.isSuperSimple=!+t.shear.toFixed(9)&&t.scalex.toFixed(9)==t.scaley.toFixed(9)&&!t.rotate,t.noRotation=!+t.shear.toFixed(9)&&!t.rotate,t},t.toTransformString=function(t){var e=t||this[q]();return e.isSimple?(e.scalex=+e.scalex.toFixed(4),e.scaley=+e.scaley.toFixed(4),e.rotate=+e.rotate.toFixed(4),(e.dx||e.dy?"t"+[e.dx,e.dy]:R)+(1!=e.scalex||1!=e.scaley?"s"+[e.scalex,e.scaley,0,0]:R)+(e.rotate?"r"+[e.rotate,0,0]:R)):"m"+[this.get(0),this.get(1),this.get(2),this.get(3),this.get(4),this.get(5)]}}(g.prototype);for(var he=function(){this.returnValue=!1},ue=function(){return this.originalEvent.preventDefault()},ce=function(){this.cancelBubble=!0},fe=function(){return this.originalEvent.stopPropagation()},pe=function(t){var e=T.doc.documentElement.scrollTop||T.doc.body.scrollTop,r=T.doc.documentElement.scrollLeft||T.doc.body.scrollLeft;return{x:t.clientX+r,y:t.clientY+e}},de=function(){return T.doc.addEventListener?function(t,e,r,i){var n=function(t){var e=pe(t);return r.call(i,t,e.x,e.y)};if(t.addEventListener(e,n,!1),F&&V[e]){var a=function(e){for(var n=pe(e),a=e,s=0,o=e.targetTouches&&e.targetTouches.length;s<o;s++)if(e.targetTouches[s].target==t){e=e.targetTouches[s],e.originalEvent=a,e.preventDefault=ue,e.stopPropagation=fe;break}return r.call(i,e,n.x,n.y)};t.addEventListener(V[e],a,!1)}return function(){return t.removeEventListener(e,n,!1),F&&V[e]&&t.removeEventListener(V[e],a,!1),!0}}:T.doc.attachEvent?function(t,e,r,i){var n=function(t){t=t||T.win.event;var e=T.doc.documentElement.scrollTop||T.doc.body.scrollTop,n=T.doc.documentElement.scrollLeft||T.doc.body.scrollLeft,a=t.clientX+n,s=t.clientY+e;return t.preventDefault=t.preventDefault||he,t.stopPropagation=t.stopPropagation||ce,r.call(i,t,a,s)};t.attachEvent("on"+e,n);var a=function(){return t.detachEvent("on"+e,n),!0};return a}:void 0}(),ge=[],ve=function(e){for(var r=e.clientX,i=e.clientY,n=T.doc.documentElement.scrollTop||T.doc.body.scrollTop,a=T.doc.documentElement.scrollLeft||T.doc.body.scrollLeft,s,o=ge.length;o--;){if(s=ge[o],F&&e.touches){for(var l=e.touches.length,h;l--;)if(h=e.touches[l],h.identifier==s.el._drag.id){r=h.clientX,i=h.clientY,(e.originalEvent?e.originalEvent:e).preventDefault();break}}else e.preventDefault();var u=s.el.node,c,f=u.nextSibling,p=u.parentNode,d=u.style.display;T.win.opera&&p.removeChild(u),u.style.display="none",c=s.el.paper.getElementByPoint(r,i),u.style.display=d,T.win.opera&&(f?p.insertBefore(u,f):p.appendChild(u)),c&&t("raphael.drag.over."+s.el.id,s.el,c),r+=a,i+=n,t("raphael.drag.move."+s.el.id,s.move_scope||s.el,r-s.el._drag.x,i-s.el._drag.y,r,i,e)}},xe=function(r){e.unmousemove(ve).unmouseup(xe);for(var i=ge.length,n;i--;)n=ge[i],n.el._drag={},t("raphael.drag.end."+n.el.id,n.end_scope||n.start_scope||n.move_scope||n.el,r);ge=[]},ye=e.el={},me=D.length;me--;)!function(t){e[t]=ye[t]=function(r,i){return e.is(r,"function")&&(this.events=this.events||[],this.events.push({name:t,f:r,unbind:de(this.shape||this.node||T.doc,t,r,i||this)})),this},e["un"+t]=ye["un"+t]=function(r){for(var i=this.events||[],n=i.length;n--;)i[n].name!=t||!e.is(r,"undefined")&&i[n].f!=r||(i[n].unbind(),i.splice(n,1),!i.length&&delete this.events);return this}}(D[me]);ye.data=function(r,i){var n=wt[this.id]=wt[this.id]||{};if(0==arguments.length)return n;if(1==arguments.length){if(e.is(r,"object")){for(var a in r)r[A](a)&&this.data(a,r[a]);return this}return t("raphael.data.get."+this.id,this,n[r],r),n[r]}return n[r]=i,t("raphael.data.set."+this.id,this,i,r),this},ye.removeData=function(t){return null==t?wt[this.id]={}:wt[this.id]&&delete wt[this.id][t],this},ye.getData=function(){return r(wt[this.id]||{})},ye.hover=function(t,e,r,i){return this.mouseover(t,r).mouseout(e,i||r)},ye.unhover=function(t,e){return this.unmouseover(t).unmouseout(e)};var be=[];ye.drag=function(r,i,n,a,s,o){function l(l){(l.originalEvent||l).preventDefault();var h=l.clientX,u=l.clientY,c=T.doc.documentElement.scrollTop||T.doc.body.scrollTop,f=T.doc.documentElement.scrollLeft||T.doc.body.scrollLeft;if(this._drag.id=l.identifier,F&&l.touches)for(var p=l.touches.length,d;p--;)if(d=l.touches[p],this._drag.id=d.identifier,d.identifier==this._drag.id){h=d.clientX,u=d.clientY;break}this._drag.x=h+f,this._drag.y=u+c,!ge.length&&e.mousemove(ve).mouseup(xe),ge.push({el:this,move_scope:a,start_scope:s,end_scope:o}),i&&t.on("raphael.drag.start."+this.id,i),r&&t.on("raphael.drag.move."+this.id,r),n&&t.on("raphael.drag.end."+this.id,n),t("raphael.drag.start."+this.id,s||a||this,l.clientX+f,l.clientY+c,l)}return this._drag={},be.push({el:this,start:l}),this.mousedown(l),this},ye.onDragOver=function(e){e?t.on("raphael.drag.over."+this.id,e):t.unbind("raphael.drag.over."+this.id)},ye.undrag=function(){for(var r=be.length;r--;)be[r].el==this&&(this.unmousedown(be[r].start),be.splice(r,1),t.unbind("raphael.drag.*."+this.id));!be.length&&e.unmousemove(ve).unmouseup(xe),ge=[]},N.circle=function(t,r,i){var n=e._engine.circle(this,t||0,r||0,i||0);return this.__set__&&this.__set__.push(n),n},N.rect=function(t,r,i,n,a){var s=e._engine.rect(this,t||0,r||0,i||0,n||0,a||0);return this.__set__&&this.__set__.push(s),s},N.ellipse=function(t,r,i,n){var a=e._engine.ellipse(this,t||0,r||0,i||0,n||0);return this.__set__&&this.__set__.push(a),a},N.path=function(t){t&&!e.is(t,Z)&&!e.is(t[0],Q)&&(t+=R);var r=e._engine.path(e.format[z](e,arguments),this);return this.__set__&&this.__set__.push(r),r},N.image=function(t,r,i,n,a){var s=e._engine.image(this,t||"about:blank",r||0,i||0,n||0,a||0);return this.__set__&&this.__set__.push(s),s},N.text=function(t,r,i){var n=e._engine.text(this,t||0,r||0,I(i));return this.__set__&&this.__set__.push(n),n},N.set=function(t){!e.is(t,"array")&&(t=Array.prototype.splice.call(arguments,0,arguments.length));var r=new ze(t);return this.__set__&&this.__set__.push(r),r.paper=this,r.type="set",r},N.setStart=function(t){this.__set__=t||this.set()},N.setFinish=function(t){var e=this.__set__;return delete this.__set__,e},N.getSize=function(){var t=this.canvas.parentNode;return{width:t.offsetWidth,height:t.offsetHeight}},N.setSize=function(t,r){return e._engine.setSize.call(this,t,r)},N.setViewBox=function(t,r,i,n,a){return e._engine.setViewBox.call(this,t,r,i,n,a)},N.top=N.bottom=null,N.raphael=e;var _e=function(t){var e=t.getBoundingClientRect(),r=t.ownerDocument,i=r.body,n=r.documentElement,a=n.clientTop||i.clientTop||0,s=n.clientLeft||i.clientLeft||0,o=e.top+(T.win.pageYOffset||n.scrollTop||i.scrollTop)-a,l=e.left+(T.win.pageXOffset||n.scrollLeft||i.scrollLeft)-s;return{y:o,x:l}};N.getElementByPoint=function(t,e){var r=this,i=r.canvas,n=T.doc.elementFromPoint(t,e);if(T.win.opera&&"svg"==n.tagName){var a=_e(i),s=i.createSVGRect();s.x=t-a.x,s.y=e-a.y,s.width=s.height=1;var o=i.getIntersectionList(s,null);o.length&&(n=o[o.length-1])}if(!n)return null;for(;n.parentNode&&n!=i.parentNode&&!n.raphael;)n=n.parentNode;return n==r.canvas.parentNode&&(n=i),n=n&&n.raphael?r.getById(n.raphaelid):null},N.getElementsByBBox=function(t){var r=this.set();return this.forEach(function(i){e.isBBoxIntersect(i.getBBox(),t)&&r.push(i)}),r},N.getById=function(t){for(var e=this.bottom;e;){if(e.id==t)return e;e=e.next}return null},N.forEach=function(t,e){for(var r=this.bottom;r;){if(t.call(e,r)===!1)return this;r=r.next}return this},N.getElementsByPoint=function(t,e){var r=this.set();return this.forEach(function(i){i.isPointInside(t,e)&&r.push(i)}),r},ye.isPointInside=function(t,r){var i=this.realPath=Et[this.type](this);return this.attr("transform")&&this.attr("transform").length&&(i=e.transformPath(i,this.attr("transform"))),e.isPointInsidePath(i,t,r)},ye.getBBox=function(t){if(this.removed)return{};var e=this._;return t?(!e.dirty&&e.bboxwt||(this.realPath=Et[this.type](this),e.bboxwt=Ot(this.realPath),e.bboxwt.toString=x,e.dirty=0),e.bboxwt):((e.dirty||e.dirtyT||!e.bbox)&&(!e.dirty&&this.realPath||(e.bboxwt=0,this.realPath=Et[this.type](this)),e.bbox=Ot(Mt(this.realPath,this.matrix)),e.bbox.toString=x,e.dirty=e.dirtyT=0),e.bbox)},ye.clone=function(){if(this.removed)return null;var t=this.paper[this.type]().attr(this.attr());return this.__set__&&this.__set__.push(t),t},ye.glow=function(t){if("text"==this.type)return null;t=t||{};var e={width:(t.width||10)+(+this.attr("stroke-width")||1),fill:t.fill||!1,opacity:null==t.opacity?.5:t.opacity,offsetx:t.offsetx||0,offsety:t.offsety||0,color:t.color||"#000"},r=e.width/2,i=this.paper,n=i.set(),a=this.realPath||Et[this.type](this);a=this.matrix?Mt(a,this.matrix):a;for(var s=1;s<r+1;s++)n.push(i.path(a).attr({stroke:e.color,fill:e.fill?e.color:"none","stroke-linejoin":"round","stroke-linecap":"round","stroke-width":+(e.width/r*s).toFixed(3),opacity:+(e.opacity/r).toFixed(3)}));return n.insertBefore(this).translate(e.offsetx,e.offsety)};var we={},ke=function(t,r,i,n,a,s,o,u,c){return null==c?l(t,r,i,n,a,s,o,u):e.findDotsAtSegment(t,r,i,n,a,s,o,u,h(t,r,i,n,a,s,o,u,c))},Be=function(t,r){return function(i,n,a){i=Qt(i);for(var s,o,l,h,u="",c={},f,p=0,d=0,g=i.length;d<g;d++){if(l=i[d],"M"==l[0])s=+l[1],o=+l[2];else{if(h=ke(s,o,l[1],l[2],l[3],l[4],l[5],l[6]),p+h>n){if(r&&!c.start){if(f=ke(s,o,l[1],l[2],l[3],l[4],l[5],l[6],n-p),u+=["C"+f.start.x,f.start.y,f.m.x,f.m.y,f.x,f.y],a)return u;c.start=u,u=["M"+f.x,f.y+"C"+f.n.x,f.n.y,f.end.x,f.end.y,l[5],l[6]].join(),p+=h,s=+l[5],o=+l[6];continue}if(!t&&!r)return f=ke(s,o,l[1],l[2],l[3],l[4],l[5],l[6],n-p),{x:f.x,y:f.y,alpha:f.alpha}}p+=h,s=+l[5],o=+l[6]}u+=l.shift()+l}return c.end=u,f=t?p:r?c:e.findDotsAtSegment(s,o,l[0],l[1],l[2],l[3],l[4],l[5],1),f.alpha&&(f={x:f.x,y:f.y,alpha:f.alpha}),f}},Ce=Be(1),Se=Be(),Ae=Be(0,1);e.getTotalLength=Ce,e.getPointAtLength=Se,e.getSubpath=function(t,e,r){if(this.getTotalLength(t)-r<1e-6)return Ae(t,e).end;var i=Ae(t,r,1);return e?Ae(i,e).end:i},ye.getTotalLength=function(){var t=this.getPath();if(t)return this.node.getTotalLength?this.node.getTotalLength():Ce(t)},ye.getPointAtLength=function(t){var e=this.getPath();if(e)return Se(e,t)},ye.getPath=function(){var t,r=e._getPath[this.type];if("text"!=this.type&&"set"!=this.type)return r&&(t=r(this)),t},ye.getSubpath=function(t,r){var i=this.getPath();if(i)return e.getSubpath(i,t,r)};var Te=e.easing_formulas={linear:function(t){return t},"<":function(t){return X(t,1.7)},">":function(t){return X(t,.48)},"<>":function(t){var e=.48-t/1.04,r=Y.sqrt(.1734+e*e),i=r-e,n=X(H(i),1/3)*(i<0?-1:1),a=-r-e,s=X(H(a),1/3)*(a<0?-1:1),o=n+s+.5;return 3*(1-o)*o*o+o*o*o},backIn:function(t){var e=1.70158;return t*t*((e+1)*t-e)},backOut:function(t){t-=1;var e=1.70158;return t*t*((e+1)*t+e)+1},elastic:function(t){return t==!!t?t:X(2,-10*t)*Y.sin((t-.075)*(2*U)/.3)+1},bounce:function(t){var e=7.5625,r=2.75,i;return t<1/r?i=e*t*t:t<2/r?(t-=1.5/r,i=e*t*t+.75):t<2.5/r?(t-=2.25/r,i=e*t*t+.9375):(t-=2.625/r,i=e*t*t+.984375),i}};Te.easeIn=Te["ease-in"]=Te["<"],Te.easeOut=Te["ease-out"]=Te[">"],Te.easeInOut=Te["ease-in-out"]=Te["<>"],Te["back-in"]=Te.backIn,Te["back-out"]=Te.backOut;var Ee=[],Me=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){setTimeout(t,16)},Ne=function(){for(var r=+new Date,i=0;i<Ee.length;i++){var n=Ee[i];if(!n.el.removed&&!n.paused){var a=r-n.start,s=n.ms,o=n.easing,l=n.from,h=n.diff,u=n.to,c=n.t,f=n.el,p={},d,g={},v;if(n.initstatus?(a=(n.initstatus*n.anim.top-n.prev)/(n.percent-n.prev)*s,n.status=n.initstatus,delete n.initstatus,n.stop&&Ee.splice(i--,1)):n.status=(n.prev+(n.percent-n.prev)*(a/s))/n.anim.top,!(a<0))if(a<s){var x=o(a/s);for(var y in l)if(l[A](y)){switch(pt[y]){case $:d=+l[y]+x*s*h[y];break;case"colour":d="rgb("+[Le(ot(l[y].r+x*s*h[y].r)),Le(ot(l[y].g+x*s*h[y].g)),Le(ot(l[y].b+x*s*h[y].b))].join(",")+")";break;case"path":d=[];for(var m=0,_=l[y].length;m<_;m++){d[m]=[l[y][m][0]];for(var w=1,k=l[y][m].length;w<k;w++)d[m][w]=+l[y][m][w]+x*s*h[y][m][w];d[m]=d[m].join(j)}d=d.join(j);break;case"transform":if(h[y].real)for(d=[],m=0,_=l[y].length;m<_;m++)for(d[m]=[l[y][m][0]],w=1,k=l[y][m].length;w<k;w++)d[m][w]=l[y][m][w]+x*s*h[y][m][w];else{var B=function(t){return+l[y][t]+x*s*h[y][t]};d=[["m",B(0),B(1),B(2),B(3),B(4),B(5)]]}break;case"csv":if("clip-rect"==y)for(d=[],m=4;m--;)d[m]=+l[y][m]+x*s*h[y][m];break;default:var C=[][P](l[y]);for(d=[],m=f.paper.customAttributes[y].length;m--;)d[m]=+C[m]+x*s*h[y][m]}p[y]=d}f.attr(p),function(e,r,i){setTimeout(function(){t("raphael.anim.frame."+e,r,i)})}(f.id,f,n.anim)}else{if(function(r,i,n){setTimeout(function(){t("raphael.anim.frame."+i.id,i,n),t("raphael.anim.finish."+i.id,i,n),e.is(r,"function")&&r.call(i)})}(n.callback,f,n.anim),f.attr(u),Ee.splice(i--,1),n.repeat>1&&!n.next){for(v in u)u[A](v)&&(g[v]=n.totalOrigin[v]);n.el.attr(g),b(n.anim,n.el,n.anim.percents[0],null,n.totalOrigin,n.repeat-1)}n.next&&!n.stop&&b(n.anim,n.el,n.next,null,n.totalOrigin,n.repeat)}}}Ee.length&&Me(Ne)},Le=function(t){return t>255?255:t<0?0:t};ye.animateWith=function(t,r,i,n,a,s){var o=this;if(o.removed)return s&&s.call(o),o;var l=i instanceof m?i:e.animation(i,n,a,s),h,u;b(l,o,l.percents[0],null,o.attr());for(var c=0,f=Ee.length;c<f;c++)if(Ee[c].anim==r&&Ee[c].el==t){Ee[f-1].start=Ee[c].start;break}return o},ye.onAnimation=function(e){return e?t.on("raphael.anim.frame."+this.id,e):t.unbind("raphael.anim.frame."+this.id),this},m.prototype.delay=function(t){var e=new m(this.anim,this.ms);return e.times=this.times,e.del=+t||0,e},m.prototype.repeat=function(t){var e=new m(this.anim,this.ms);return e.del=this.del,e.times=Y.floor(W(t,0))||1,e},e.animation=function(t,r,i,n){if(t instanceof m)return t;!e.is(i,"function")&&i||(n=n||i||null,i=null),t=Object(t),r=+r||0;var a={},s,o;for(o in t)t[A](o)&&ht(o)!=o&&ht(o)+"%"!=o&&(s=!0,a[o]=t[o]);if(s)return i&&(a.easing=i),n&&(a.callback=n),new m({100:a},r);if(n){var l=0;for(var h in t){var u=ut(h);t[A](h)&&u>l&&(l=u)}l+="%",!t[l].callback&&(t[l].callback=n)}return new m(t,r)},ye.animate=function(t,r,i,n){var a=this;if(a.removed)return n&&n.call(a),a;var s=t instanceof m?t:e.animation(t,r,i,n);return b(s,a,s.percents[0],null,a.attr()),a},ye.setTime=function(t,e){return t&&null!=e&&this.status(t,G(e,t.ms)/t.ms),this},ye.status=function(t,e){var r=[],i=0,n,a;if(null!=e)return b(t,this,-1,G(e,1)),this;for(n=Ee.length;i<n;i++)if(a=Ee[i],a.el.id==this.id&&(!t||a.anim==t)){if(t)return a.status;r.push({anim:a.anim,status:a.status})}return t?0:r},ye.pause=function(e){for(var r=0;r<Ee.length;r++)Ee[r].el.id!=this.id||e&&Ee[r].anim!=e||t("raphael.anim.pause."+this.id,this,Ee[r].anim)!==!1&&(Ee[r].paused=!0);return this},ye.resume=function(e){for(var r=0;r<Ee.length;r++)if(Ee[r].el.id==this.id&&(!e||Ee[r].anim==e)){var i=Ee[r];t("raphael.anim.resume."+this.id,this,i.anim)!==!1&&(delete i.paused,this.status(i.anim,i.status))}return this},ye.stop=function(e){for(var r=0;r<Ee.length;r++)Ee[r].el.id!=this.id||e&&Ee[r].anim!=e||t("raphael.anim.stop."+this.id,this,Ee[r].anim)!==!1&&Ee.splice(r--,1);return this},t.on("raphael.remove",_),t.on("raphael.clear",_),ye.toString=function(){return"Raphaël’s object"};var ze=function(t){if(this.items=[],this.length=0,this.type="set",t)for(var e=0,r=t.length;e<r;e++)!t[e]||t[e].constructor!=ye.constructor&&t[e].constructor!=ze||(this[this.items.length]=this.items[this.items.length]=t[e],this.length++)},Pe=ze.prototype;Pe.push=function(){for(var t,e,r=0,i=arguments.length;r<i;r++)t=arguments[r],!t||t.constructor!=ye.constructor&&t.constructor!=ze||(e=this.items.length,this[e]=this.items[e]=t,this.length++);return this},Pe.pop=function(){return this.length&&delete this[this.length--],this.items.pop()},Pe.forEach=function(t,e){for(var r=0,i=this.items.length;r<i;r++)if(t.call(e,this.items[r],r)===!1)return this;return this};for(var Fe in ye)ye[A](Fe)&&(Pe[Fe]=function(t){return function(){var e=arguments;return this.forEach(function(r){r[t][z](r,e)})}}(Fe));return Pe.attr=function(t,r){if(t&&e.is(t,Q)&&e.is(t[0],"object"))for(var i=0,n=t.length;i<n;i++)this.items[i].attr(t[i]);else for(var a=0,s=this.items.length;a<s;a++)this.items[a].attr(t,r);return this},Pe.clear=function(){for(;this.length;)this.pop()},Pe.splice=function(t,e,r){t=t<0?W(this.length+t,0):t,e=W(0,G(this.length-t,e));var i=[],n=[],a=[],s;for(s=2;s<arguments.length;s++)a.push(arguments[s]);for(s=0;s<e;s++)n.push(this[t+s]);for(;s<this.length-t;s++)i.push(this[t+s]);var o=a.length;for(s=0;s<o+i.length;s++)this.items[t+s]=this[t+s]=s<o?a[s]:i[s-o];for(s=this.items.length=this.length-=e-o;this[s];)delete this[s++];return new ze(n)},Pe.exclude=function(t){for(var e=0,r=this.length;e<r;e++)if(this[e]==t)return this.splice(e,1),!0},Pe.animate=function(t,r,i,n){(e.is(i,"function")||!i)&&(n=i||null);var a=this.items.length,s=a,o,l=this,h;if(!a)return this;n&&(h=function(){!--a&&n.call(l)}),i=e.is(i,Z)?i:h;var u=e.animation(t,r,i,h);for(o=this.items[--s].animate(u);s--;)this.items[s]&&!this.items[s].removed&&this.items[s].animateWith(o,u,u),this.items[s]&&!this.items[s].removed||a--;return this},Pe.insertAfter=function(t){for(var e=this.items.length;e--;)this.items[e].insertAfter(t);return this},Pe.getBBox=function(){for(var t=[],e=[],r=[],i=[],n=this.items.length;n--;)if(!this.items[n].removed){var a=this.items[n].getBBox();t.push(a.x),e.push(a.y),r.push(a.x+a.width),i.push(a.y+a.height)}return t=G[z](0,t),e=G[z](0,e),r=W[z](0,r),i=W[z](0,i),{x:t,y:e,x2:r,y2:i,width:r-t,height:i-e}},Pe.clone=function(t){t=this.paper.set();for(var e=0,r=this.items.length;e<r;e++)t.push(this.items[e].clone());return t},Pe.toString=function(){return"Raphaël‘s set"},Pe.glow=function(t){var e=this.paper.set();return this.forEach(function(r,i){var n=r.glow(t);null!=n&&n.forEach(function(t,r){e.push(t)})}),e},Pe.isPointInside=function(t,e){var r=!1;return this.forEach(function(i){if(i.isPointInside(t,e))return r=!0,!1}),r},e.registerFont=function(t){if(!t.face)return t;this.fonts=this.fonts||{};var e={w:t.w,face:{},glyphs:{}},r=t.face["font-family"];for(var i in t.face)t.face[A](i)&&(e.face[i]=t.face[i]);if(this.fonts[r]?this.fonts[r].push(e):this.fonts[r]=[e],!t.svg){e.face["units-per-em"]=ut(t.face["units-per-em"],10);for(var n in t.glyphs)if(t.glyphs[A](n)){var a=t.glyphs[n];if(e.glyphs[n]={w:a.w,k:{},d:a.d&&"M"+a.d.replace(/[mlcxtrv]/g,function(t){return{l:"L",c:"C",x:"z",t:"m",r:"l",v:"c"}[t]||"M"})+"z"},a.k)for(var s in a.k)a[A](s)&&(e.glyphs[n].k[s]=a.k[s])}}return t},N.getFont=function(t,r,i,n){if(n=n||"normal",i=i||"normal",r=+r||{normal:400,bold:700,lighter:300,bolder:800}[r]||400,e.fonts){var a=e.fonts[t];if(!a){var s=new RegExp("(^|\\s)"+t.replace(/[^\w\d\s+!~.:_-]/g,R)+"(\\s|$)","i");for(var o in e.fonts)if(e.fonts[A](o)&&s.test(o)){a=e.fonts[o];break}}var l;if(a)for(var h=0,u=a.length;h<u&&(l=a[h],l.face["font-weight"]!=r||l.face["font-style"]!=i&&l.face["font-style"]||l.face["font-stretch"]!=n);h++);return l}},N.print=function(t,r,i,n,a,s,o,l){s=s||"middle",o=W(G(o||0,1),-1),l=W(G(l||1,3),1);var h=I(i)[q](R),u=0,c=0,f=R,p;if(e.is(n,"string")&&(n=this.getFont(n)),n){p=(a||16)/n.face["units-per-em"];for(var d=n.face.bbox[q](k),g=+d[0],v=d[3]-d[1],x=0,y=+d[1]+("baseline"==s?v+ +n.face.descent:v/2),m=0,b=h.length;m<b;m++){if("\n"==h[m])u=0,w=0,c=0,x+=v*l;else{var _=c&&n.glyphs[h[m-1]]||{},w=n.glyphs[h[m]];u+=c?(_.w||n.w)+(_.k&&_.k[h[m]]||0)+n.w*o:0,c=1}w&&w.d&&(f+=e.transformPath(w.d,["t",u*p,x*p,"s",p,p,g,y,"t",(t-g)/p,(r-y)/p]))}}return this.path(f).attr({fill:"#000",stroke:"none"})},N.add=function(t){if(e.is(t,"array"))for(var r=this.set(),i=0,n=t.length,a;i<n;i++)a=t[i]||{},B[A](a.type)&&r.push(this[a.type]().attr(a));return r},e.format=function(t,r){var i=e.is(r,Q)?[0][P](r):arguments;return t&&e.is(t,Z)&&i.length-1&&(t=t.replace(C,function(t,e){return null==i[++e]?R:i[e]})),t||R},e.fullfill=function(){var t=/\{([^\}]+)\}/g,e=/(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g,r=function(t,r,i){var n=i;return r.replace(e,function(t,e,r,i,a){e=e||i,n&&(e in n&&(n=n[e]),"function"==typeof n&&a&&(n=n()))}),n=(null==n||n==i?t:n)+""};return function(e,i){return String(e).replace(t,function(t,e){return r(t,e,i)})}}(),e.ninja=function(){if(E.was)T.win.Raphael=E.is;else{window.Raphael=void 0;try{delete window.Raphael}catch(t){}}return e},e.st=Pe,t.on("raphael.DOMload",function(){w=!0}),function(t,r,i){function n(){/in/.test(t.readyState)?setTimeout(n,9):e.eve("raphael.DOMload")}null==t.readyState&&t.addEventListener&&(t.addEventListener(r,i=function(){t.removeEventListener(r,i,!1),t.readyState="complete"},!1),t.readyState="loading"),n()}(document,"DOMContentLoaded"),e}.apply(e,i),!(void 0!==n&&(t.exports=n))},function(t,e,r){var i,n;!function(r){var a="0.5.0",s="hasOwnProperty",o=/[\.\/]/,l=/\s*,\s*/,h="*",u=function(){},c=function(t,e){return t-e},f,p,d={n:{}},g=function(){for(var t=0,e=this.length;t<e;t++)if("undefined"!=typeof this[t])return this[t]},v=function(){for(var t=this.length;--t;)if("undefined"!=typeof this[t])return this[t]},x=Object.prototype.toString,y=String,m=Array.isArray||function(t){return t instanceof Array||"[object Array]"==x.call(t)};eve=function(t,e){var r=d,i=p,n=Array.prototype.slice.call(arguments,2),a=eve.listeners(t),s=0,o=!1,l,h=[],u={},x=[],y=f,m=[];x.firstDefined=g,x.lastDefined=v,f=t,p=0;for(var b=0,_=a.length;b<_;b++)"zIndex"in a[b]&&(h.push(a[b].zIndex),a[b].zIndex<0&&(u[a[b].zIndex]=a[b]));for(h.sort(c);h[s]<0;)if(l=u[h[s++]],x.push(l.apply(e,n)),p)return p=i,x;for(b=0;b<_;b++)if(l=a[b],"zIndex"in l)if(l.zIndex==h[s]){if(x.push(l.apply(e,n)),p)break;do if(s++,l=u[h[s]],l&&x.push(l.apply(e,n)),p)break;while(l)}else u[l.zIndex]=l;else if(x.push(l.apply(e,n)),p)break;return p=i,f=y,x},eve._events=d,eve.listeners=function(t){var e=m(t)?t:t.split(o),r=d,i,n,a,s,l,u,c,f,p=[r],g=[];for(s=0,l=e.length;s<l;s++){for(f=[],u=0,c=p.length;u<c;u++)for(r=p[u].n,n=[r[e[s]],r[h]],a=2;a--;)i=n[a],i&&(f.push(i),g=g.concat(i.f||[]));p=f}return g},eve.separator=function(t){t?(t=y(t).replace(/(?=[\.\^\]\[\-])/g,"\\"),t="["+t+"]",o=new RegExp(t)):o=/[\.\/]/},eve.on=function(t,e){if("function"!=typeof e)return function(){};for(var r=m(t)?m(t[0])?t:[t]:y(t).split(l),i=0,n=r.length;i<n;i++)!function(t){for(var r=m(t)?t:y(t).split(o),i=d,n,a=0,s=r.length;a<s;a++)i=i.n,i=i.hasOwnProperty(r[a])&&i[r[a]]||(i[r[a]]={n:{}});for(i.f=i.f||[],a=0,s=i.f.length;a<s;a++)if(i.f[a]==e){n=!0;break}!n&&i.f.push(e)}(r[i]);return function(t){+t==+t&&(e.zIndex=+t)}},eve.f=function(t){var e=[].slice.call(arguments,1);return function(){eve.apply(null,[t,null].concat(e).concat([].slice.call(arguments,0)))}},eve.stop=function(){p=1},eve.nt=function(t){var e=m(f)?f.join("."):f;return t?new RegExp("(?:\\.|\\/|^)"+t+"(?:\\.|\\/|$)").test(e):e},eve.nts=function(){return m(f)?f:f.split(o)},eve.off=eve.unbind=function(t,e){if(!t)return void(eve._events=d={n:{}});var r=m(t)?m(t[0])?t:[t]:y(t).split(l);if(r.length>1)for(var i=0,n=r.length;i<n;i++)eve.off(r[i],e);else{r=m(t)?t:y(t).split(o);var a,u,c,i,n,f,p,g=[d];for(i=0,n=r.length;i<n;i++)for(f=0;f<g.length;f+=c.length-2){if(c=[f,1],a=g[f].n,r[i]!=h)a[r[i]]&&c.push(a[r[i]]);else for(u in a)a[s](u)&&c.push(a[u]);g.splice.apply(g,c)}for(i=0,n=g.length;i<n;i++)for(a=g[i];a.n;){if(e){if(a.f){for(f=0,p=a.f.length;f<p;f++)if(a.f[f]==e){a.f.splice(f,1);break}!a.f.length&&delete a.f}for(u in a.n)if(a.n[s](u)&&a.n[u].f){var v=a.n[u].f;for(f=0,p=v.length;f<p;f++)if(v[f]==e){v.splice(f,1);break}!v.length&&delete a.n[u].f}}else{delete a.f;for(u in a.n)a.n[s](u)&&a.n[u].f&&delete a.n[u].f}a=a.n}}},eve.once=function(t,e){var r=function(){return eve.off(t,r),e.apply(this,arguments)};return eve.on(t,r)},eve.version=a,eve.toString=function(){return"You are running Eve "+a},"undefined"!=typeof t&&t.exports?t.exports=eve:(i=[],n=function(){return eve}.apply(e,i),!(void 0!==n&&(t.exports=n)))}(this)},function(t,e,r){var i,n;i=[r(1)],n=function(t){if(!t||t.svg){var e="hasOwnProperty",r=String,i=parseFloat,n=parseInt,a=Math,s=a.max,o=a.abs,l=a.pow,h=/[, ]+/,u=t.eve,c="",f=" ",p="http://www.w3.org/1999/xlink",d={block:"M5,0 0,2.5 5,5z",classic:"M5,0 0,2.5 5,5 3.5,3 3.5,2z",diamond:"M2.5,0 5,2.5 2.5,5 0,2.5z",open:"M6,1 1,3.5 6,6",oval:"M2.5,0A2.5,2.5,0,0,1,2.5,5 2.5,2.5,0,0,1,2.5,0z"},g={};t.toString=function(){return"Your browser supports SVG.\nYou are running Raphaël "+this.version};var v=function(i,n){if(n){"string"==typeof i&&(i=v(i));for(var a in n)n[e](a)&&("xlink:"==a.substring(0,6)?i.setAttributeNS(p,a.substring(6),r(n[a])):i.setAttribute(a,r(n[a])))}else i=t._g.doc.createElementNS("http://www.w3.org/2000/svg",i),i.style&&(i.style.webkitTapHighlightColor="rgba(0,0,0,0)");return i},x=function(e,n){var h="linear",u=e.id+n,f=.5,p=.5,d=e.node,g=e.paper,x=d.style,y=t._g.doc.getElementById(u);if(!y){if(n=r(n).replace(t._radial_gradient,function(t,e,r){if(h="radial",e&&r){f=i(e),p=i(r);var n=2*(p>.5)-1;l(f-.5,2)+l(p-.5,2)>.25&&(p=a.sqrt(.25-l(f-.5,2))*n+.5)&&.5!=p&&(p=p.toFixed(5)-1e-5*n)}return c}),n=n.split(/\s*\-\s*/),"linear"==h){var b=n.shift();if(b=-i(b),isNaN(b))return null;var _=[0,0,a.cos(t.rad(b)),a.sin(t.rad(b))],w=1/(s(o(_[2]),o(_[3]))||1);_[2]*=w,_[3]*=w,_[2]<0&&(_[0]=-_[2],_[2]=0),_[3]<0&&(_[1]=-_[3],_[3]=0)}var k=t._parseDots(n);if(!k)return null;if(u=u.replace(/[\(\)\s,\xb0#]/g,"_"),e.gradient&&u!=e.gradient.id&&(g.defs.removeChild(e.gradient),delete e.gradient),!e.gradient){y=v(h+"Gradient",{id:u}),e.gradient=y,v(y,"radial"==h?{fx:f,fy:p}:{x1:_[0],y1:_[1],x2:_[2],y2:_[3],gradientTransform:e.matrix.invert()}),g.defs.appendChild(y);for(var B=0,C=k.length;B<C;B++)y.appendChild(v("stop",{offset:k[B].offset?k[B].offset:B?"100%":"0%","stop-color":k[B].color||"#fff","stop-opacity":isFinite(k[B].opacity)?k[B].opacity:1}))}}return v(d,{fill:m(u),opacity:1,"fill-opacity":1}),x.fill=c,x.opacity=1,x.fillOpacity=1,1},y=function(){var t=document.documentMode;return t&&(9===t||10===t)},m=function(t){if(y())return"url('#"+t+"')";var e=document.location,r=e.protocol+"//"+e.host+e.pathname+e.search;return"url('"+r+"#"+t+"')"},b=function(t){var e=t.getBBox(1);v(t.pattern,{patternTransform:t.matrix.invert()+" translate("+e.x+","+e.y+")"})},_=function(i,n,a){if("path"==i.type){for(var s=r(n).toLowerCase().split("-"),o=i.paper,l=a?"end":"start",h=i.node,u=i.attrs,f=u["stroke-width"],p=s.length,x="classic",y,m,b,_,w,k=3,B=3,C=5;p--;)switch(s[p]){case"block":case"classic":case"oval":case"diamond":case"open":case"none":x=s[p];break;case"wide":B=5;break;case"narrow":B=2;break;case"long":k=5;break;case"short":k=2}if("open"==x?(k+=2,B+=2,C+=2,b=1,_=a?4:1,w={fill:"none",stroke:u.stroke}):(_=b=k/2,w={fill:u.stroke,stroke:"none"}),i._.arrows?a?(i._.arrows.endPath&&g[i._.arrows.endPath]--,i._.arrows.endMarker&&g[i._.arrows.endMarker]--):(i._.arrows.startPath&&g[i._.arrows.startPath]--,i._.arrows.startMarker&&g[i._.arrows.startMarker]--):i._.arrows={},"none"!=x){var S="raphael-marker-"+x,A="raphael-marker-"+l+x+k+B+"-obj"+i.id;t._g.doc.getElementById(S)?g[S]++:(o.defs.appendChild(v(v("path"),{"stroke-linecap":"round",d:d[x],id:S})),g[S]=1);var T=t._g.doc.getElementById(A),E;T?(g[A]++,E=T.getElementsByTagName("use")[0]):(T=v(v("marker"),{id:A,markerHeight:B,markerWidth:k,orient:"auto",refX:_,refY:B/2}),E=v(v("use"),{"xlink:href":"#"+S,transform:(a?"rotate(180 "+k/2+" "+B/2+") ":c)+"scale("+k/C+","+B/C+")","stroke-width":(1/((k/C+B/C)/2)).toFixed(4)}),T.appendChild(E),o.defs.appendChild(T),g[A]=1),v(E,w);var M=b*("diamond"!=x&&"oval"!=x);a?(y=i._.arrows.startdx*f||0,m=t.getTotalLength(u.path)-M*f):(y=M*f,m=t.getTotalLength(u.path)-(i._.arrows.enddx*f||0)),w={},w["marker-"+l]="url(#"+A+")",(m||y)&&(w.d=t.getSubpath(u.path,y,m)),v(h,w),i._.arrows[l+"Path"]=S,i._.arrows[l+"Marker"]=A,i._.arrows[l+"dx"]=M,i._.arrows[l+"Type"]=x,i._.arrows[l+"String"]=n}else a?(y=i._.arrows.startdx*f||0,m=t.getTotalLength(u.path)-y):(y=0,m=t.getTotalLength(u.path)-(i._.arrows.enddx*f||0)),i._.arrows[l+"Path"]&&v(h,{d:t.getSubpath(u.path,y,m)}),delete i._.arrows[l+"Path"],delete i._.arrows[l+"Marker"],delete i._.arrows[l+"dx"],delete i._.arrows[l+"Type"],delete i._.arrows[l+"String"];for(w in g)if(g[e](w)&&!g[w]){var N=t._g.doc.getElementById(w);N&&N.parentNode.removeChild(N)}}},w={"-":[3,1],".":[1,1],"-.":[3,1,1,1],"-..":[3,1,1,1,1,1],". ":[1,3],"- ":[4,3],"--":[8,3],"- .":[4,3,1,3],"--.":[8,3,1,3],"--..":[8,3,1,3,1,3]},k=function(t,e,i){if(e=w[r(e).toLowerCase()]){for(var n=t.attrs["stroke-width"]||"1",a={round:n,square:n,butt:0}[t.attrs["stroke-linecap"]||i["stroke-linecap"]]||0,s=[],o=e.length;o--;)s[o]=e[o]*n+(o%2?1:-1)*a;v(t.node,{"stroke-dasharray":s.join(",")})}else v(t.node,{"stroke-dasharray":"none"})},B=function(i,a){var l=i.node,u=i.attrs,f=l.style.visibility;l.style.visibility="hidden";for(var d in a)if(a[e](d)){if(!t._availableAttrs[e](d))continue;var g=a[d];switch(u[d]=g,d){case"blur":i.blur(g);break;case"title":var y=l.getElementsByTagName("title");if(y.length&&(y=y[0]))y.firstChild.nodeValue=g;else{y=v("title");var m=t._g.doc.createTextNode(g);y.appendChild(m),l.appendChild(y)}break;case"href":case"target":var w=l.parentNode;if("a"!=w.tagName.toLowerCase()){var B=v("a");w.insertBefore(B,l),B.appendChild(l),w=B}"target"==d?w.setAttributeNS(p,"show","blank"==g?"new":g):w.setAttributeNS(p,d,g);break;case"cursor":l.style.cursor=g;break;case"transform":i.transform(g);break;case"arrow-start":_(i,g);break;case"arrow-end":_(i,g,1);break;case"clip-rect":var C=r(g).split(h);if(4==C.length){i.clip&&i.clip.parentNode.parentNode.removeChild(i.clip.parentNode);var A=v("clipPath"),T=v("rect");A.id=t.createUUID(),v(T,{x:C[0],y:C[1],width:C[2],height:C[3]}),A.appendChild(T),i.paper.defs.appendChild(A),v(l,{"clip-path":"url(#"+A.id+")"}),i.clip=T}if(!g){var E=l.getAttribute("clip-path");if(E){var M=t._g.doc.getElementById(E.replace(/(^url\(#|\)$)/g,c));M&&M.parentNode.removeChild(M),v(l,{"clip-path":c}),delete i.clip}}break;case"path":"path"==i.type&&(v(l,{d:g?u.path=t._pathToAbsolute(g):"M0,0"}),i._.dirty=1,i._.arrows&&("startString"in i._.arrows&&_(i,i._.arrows.startString),"endString"in i._.arrows&&_(i,i._.arrows.endString,1)));break;case"width":if(l.setAttribute(d,g),i._.dirty=1,!u.fx)break;d="x",g=u.x;case"x":u.fx&&(g=-u.x-(u.width||0));case"rx":if("rx"==d&&"rect"==i.type)break;case"cx":l.setAttribute(d,g),i.pattern&&b(i),i._.dirty=1;break;case"height":if(l.setAttribute(d,g),i._.dirty=1,!u.fy)break;d="y",g=u.y;case"y":u.fy&&(g=-u.y-(u.height||0));case"ry":if("ry"==d&&"rect"==i.type)break;case"cy":l.setAttribute(d,g),i.pattern&&b(i),i._.dirty=1;break;case"r":"rect"==i.type?v(l,{rx:g,ry:g}):l.setAttribute(d,g),i._.dirty=1;break;case"src":"image"==i.type&&l.setAttributeNS(p,"href",g);break;case"stroke-width":1==i._.sx&&1==i._.sy||(g/=s(o(i._.sx),o(i._.sy))||1),l.setAttribute(d,g),u["stroke-dasharray"]&&k(i,u["stroke-dasharray"],a),
|
3 |
+
i._.arrows&&("startString"in i._.arrows&&_(i,i._.arrows.startString),"endString"in i._.arrows&&_(i,i._.arrows.endString,1));break;case"stroke-dasharray":k(i,g,a);break;case"fill":var N=r(g).match(t._ISURL);if(N){A=v("pattern");var L=v("image");A.id=t.createUUID(),v(A,{x:0,y:0,patternUnits:"userSpaceOnUse",height:1,width:1}),v(L,{x:0,y:0,"xlink:href":N[1]}),A.appendChild(L),function(e){t._preload(N[1],function(){var t=this.offsetWidth,r=this.offsetHeight;v(e,{width:t,height:r}),v(L,{width:t,height:r})})}(A),i.paper.defs.appendChild(A),v(l,{fill:"url(#"+A.id+")"}),i.pattern=A,i.pattern&&b(i);break}var z=t.getRGB(g);if(z.error){if(("circle"==i.type||"ellipse"==i.type||"r"!=r(g).charAt())&&x(i,g)){if("opacity"in u||"fill-opacity"in u){var P=t._g.doc.getElementById(l.getAttribute("fill").replace(/^url\(#|\)$/g,c));if(P){var F=P.getElementsByTagName("stop");v(F[F.length-1],{"stop-opacity":("opacity"in u?u.opacity:1)*("fill-opacity"in u?u["fill-opacity"]:1)})}}u.gradient=g,u.fill="none";break}}else delete a.gradient,delete u.gradient,!t.is(u.opacity,"undefined")&&t.is(a.opacity,"undefined")&&v(l,{opacity:u.opacity}),!t.is(u["fill-opacity"],"undefined")&&t.is(a["fill-opacity"],"undefined")&&v(l,{"fill-opacity":u["fill-opacity"]});z[e]("opacity")&&v(l,{"fill-opacity":z.opacity>1?z.opacity/100:z.opacity});case"stroke":z=t.getRGB(g),l.setAttribute(d,z.hex),"stroke"==d&&z[e]("opacity")&&v(l,{"stroke-opacity":z.opacity>1?z.opacity/100:z.opacity}),"stroke"==d&&i._.arrows&&("startString"in i._.arrows&&_(i,i._.arrows.startString),"endString"in i._.arrows&&_(i,i._.arrows.endString,1));break;case"gradient":("circle"==i.type||"ellipse"==i.type||"r"!=r(g).charAt())&&x(i,g);break;case"opacity":u.gradient&&!u[e]("stroke-opacity")&&v(l,{"stroke-opacity":g>1?g/100:g});case"fill-opacity":if(u.gradient){P=t._g.doc.getElementById(l.getAttribute("fill").replace(/^url\(#|\)$/g,c)),P&&(F=P.getElementsByTagName("stop"),v(F[F.length-1],{"stop-opacity":g}));break}default:"font-size"==d&&(g=n(g,10)+"px");var R=d.replace(/(\-.)/g,function(t){return t.substring(1).toUpperCase()});l.style[R]=g,i._.dirty=1,l.setAttribute(d,g)}}S(i,a),l.style.visibility=f},C=1.2,S=function(i,a){if("text"==i.type&&(a[e]("text")||a[e]("font")||a[e]("font-size")||a[e]("x")||a[e]("y"))){var s=i.attrs,o=i.node,l=o.firstChild?n(t._g.doc.defaultView.getComputedStyle(o.firstChild,c).getPropertyValue("font-size"),10):10;if(a[e]("text")){for(s.text=a.text;o.firstChild;)o.removeChild(o.firstChild);for(var h=r(a.text).split("\n"),u=[],f,p=0,d=h.length;p<d;p++)f=v("tspan"),p&&v(f,{dy:l*C,x:s.x}),f.appendChild(t._g.doc.createTextNode(h[p])),o.appendChild(f),u[p]=f}else for(u=o.getElementsByTagName("tspan"),p=0,d=u.length;p<d;p++)p?v(u[p],{dy:l*C,x:s.x}):v(u[0],{dy:0});v(o,{x:s.x,y:s.y}),i._.dirty=1;var g=i._getBBox(),x=s.y-(g.y+g.height/2);x&&t.is(x,"finite")&&v(u[0],{dy:x})}},A=function(t){return t.parentNode&&"a"===t.parentNode.tagName.toLowerCase()?t.parentNode:t},T=function(e,r){function i(){return("0000"+(Math.random()*Math.pow(36,5)<<0).toString(36)).slice(-5)}var n=0,a=0;this[0]=this.node=e,e.raphael=!0,this.id=i(),e.raphaelid=this.id,this.matrix=t.matrix(),this.realPath=null,this.paper=r,this.attrs=this.attrs||{},this._={transform:[],sx:1,sy:1,deg:0,dx:0,dy:0,dirty:1},!r.bottom&&(r.bottom=this),this.prev=r.top,r.top&&(r.top.next=this),r.top=this,this.next=null},E=t.el;T.prototype=E,E.constructor=T,t._engine.path=function(t,e){var r=v("path");e.canvas&&e.canvas.appendChild(r);var i=new T(r,e);return i.type="path",B(i,{fill:"none",stroke:"#000",path:t}),i},E.rotate=function(t,e,n){if(this.removed)return this;if(t=r(t).split(h),t.length-1&&(e=i(t[1]),n=i(t[2])),t=i(t[0]),null==n&&(e=n),null==e||null==n){var a=this.getBBox(1);e=a.x+a.width/2,n=a.y+a.height/2}return this.transform(this._.transform.concat([["r",t,e,n]])),this},E.scale=function(t,e,n,a){if(this.removed)return this;if(t=r(t).split(h),t.length-1&&(e=i(t[1]),n=i(t[2]),a=i(t[3])),t=i(t[0]),null==e&&(e=t),null==a&&(n=a),null==n||null==a)var s=this.getBBox(1);return n=null==n?s.x+s.width/2:n,a=null==a?s.y+s.height/2:a,this.transform(this._.transform.concat([["s",t,e,n,a]])),this},E.translate=function(t,e){return this.removed?this:(t=r(t).split(h),t.length-1&&(e=i(t[1])),t=i(t[0])||0,e=+e||0,this.transform(this._.transform.concat([["t",t,e]])),this)},E.transform=function(r){var i=this._;if(null==r)return i.transform;if(t._extractTransform(this,r),this.clip&&v(this.clip,{transform:this.matrix.invert()}),this.pattern&&b(this),this.node&&v(this.node,{transform:this.matrix}),1!=i.sx||1!=i.sy){var n=this.attrs[e]("stroke-width")?this.attrs["stroke-width"]:1;this.attr({"stroke-width":n})}return this},E.hide=function(){return this.removed||(this.node.style.display="none"),this},E.show=function(){return this.removed||(this.node.style.display=""),this},E.remove=function(){var e=A(this.node);if(!this.removed&&e.parentNode){var r=this.paper;r.__set__&&r.__set__.exclude(this),u.unbind("raphael.*.*."+this.id),this.gradient&&r.defs.removeChild(this.gradient),t._tear(this,r),e.parentNode.removeChild(e),this.removeData();for(var i in this)this[i]="function"==typeof this[i]?t._removedFactory(i):null;this.removed=!0}},E._getBBox=function(){if("none"==this.node.style.display){this.show();var t=!0}var e=!1,r;this.paper.canvas.parentElement?r=this.paper.canvas.parentElement.style:this.paper.canvas.parentNode&&(r=this.paper.canvas.parentNode.style),r&&"none"==r.display&&(e=!0,r.display="");var i={};try{i=this.node.getBBox()}catch(n){i={x:this.node.clientLeft,y:this.node.clientTop,width:this.node.clientWidth,height:this.node.clientHeight}}finally{i=i||{},e&&(r.display="none")}return t&&this.hide(),i},E.attr=function(r,i){if(this.removed)return this;if(null==r){var n={};for(var a in this.attrs)this.attrs[e](a)&&(n[a]=this.attrs[a]);return n.gradient&&"none"==n.fill&&(n.fill=n.gradient)&&delete n.gradient,n.transform=this._.transform,n}if(null==i&&t.is(r,"string")){if("fill"==r&&"none"==this.attrs.fill&&this.attrs.gradient)return this.attrs.gradient;if("transform"==r)return this._.transform;for(var s=r.split(h),o={},l=0,c=s.length;l<c;l++)r=s[l],r in this.attrs?o[r]=this.attrs[r]:t.is(this.paper.customAttributes[r],"function")?o[r]=this.paper.customAttributes[r].def:o[r]=t._availableAttrs[r];return c-1?o:o[s[0]]}if(null==i&&t.is(r,"array")){for(o={},l=0,c=r.length;l<c;l++)o[r[l]]=this.attr(r[l]);return o}if(null!=i){var f={};f[r]=i}else null!=r&&t.is(r,"object")&&(f=r);for(var p in f)u("raphael.attr."+p+"."+this.id,this,f[p]);for(p in this.paper.customAttributes)if(this.paper.customAttributes[e](p)&&f[e](p)&&t.is(this.paper.customAttributes[p],"function")){var d=this.paper.customAttributes[p].apply(this,[].concat(f[p]));this.attrs[p]=f[p];for(var g in d)d[e](g)&&(f[g]=d[g])}return B(this,f),this},E.toFront=function(){if(this.removed)return this;var e=A(this.node);e.parentNode.appendChild(e);var r=this.paper;return r.top!=this&&t._tofront(this,r),this},E.toBack=function(){if(this.removed)return this;var e=A(this.node),r=e.parentNode;r.insertBefore(e,r.firstChild),t._toback(this,this.paper);var i=this.paper;return this},E.insertAfter=function(e){if(this.removed||!e)return this;var r=A(this.node),i=A(e.node||e[e.length-1].node);return i.nextSibling?i.parentNode.insertBefore(r,i.nextSibling):i.parentNode.appendChild(r),t._insertafter(this,e,this.paper),this},E.insertBefore=function(e){if(this.removed||!e)return this;var r=A(this.node),i=A(e.node||e[0].node);return i.parentNode.insertBefore(r,i),t._insertbefore(this,e,this.paper),this},E.blur=function(e){var r=this;if(0!==+e){var i=v("filter"),n=v("feGaussianBlur");r.attrs.blur=e,i.id=t.createUUID(),v(n,{stdDeviation:+e||1.5}),i.appendChild(n),r.paper.defs.appendChild(i),r._blur=i,v(r.node,{filter:"url(#"+i.id+")"})}else r._blur&&(r._blur.parentNode.removeChild(r._blur),delete r._blur,delete r.attrs.blur),r.node.removeAttribute("filter");return r},t._engine.circle=function(t,e,r,i){var n=v("circle");t.canvas&&t.canvas.appendChild(n);var a=new T(n,t);return a.attrs={cx:e,cy:r,r:i,fill:"none",stroke:"#000"},a.type="circle",v(n,a.attrs),a},t._engine.rect=function(t,e,r,i,n,a){var s=v("rect");t.canvas&&t.canvas.appendChild(s);var o=new T(s,t);return o.attrs={x:e,y:r,width:i,height:n,rx:a||0,ry:a||0,fill:"none",stroke:"#000"},o.type="rect",v(s,o.attrs),o},t._engine.ellipse=function(t,e,r,i,n){var a=v("ellipse");t.canvas&&t.canvas.appendChild(a);var s=new T(a,t);return s.attrs={cx:e,cy:r,rx:i,ry:n,fill:"none",stroke:"#000"},s.type="ellipse",v(a,s.attrs),s},t._engine.image=function(t,e,r,i,n,a){var s=v("image");v(s,{x:r,y:i,width:n,height:a,preserveAspectRatio:"none"}),s.setAttributeNS(p,"href",e),t.canvas&&t.canvas.appendChild(s);var o=new T(s,t);return o.attrs={x:r,y:i,width:n,height:a,src:e},o.type="image",o},t._engine.text=function(e,r,i,n){var a=v("text");e.canvas&&e.canvas.appendChild(a);var s=new T(a,e);return s.attrs={x:r,y:i,"text-anchor":"middle",text:n,"font-family":t._availableAttrs["font-family"],"font-size":t._availableAttrs["font-size"],stroke:"none",fill:"#000"},s.type="text",B(s,s.attrs),s},t._engine.setSize=function(t,e){return this.width=t||this.width,this.height=e||this.height,this.canvas.setAttribute("width",this.width),this.canvas.setAttribute("height",this.height),this._viewBox&&this.setViewBox.apply(this,this._viewBox),this},t._engine.create=function(){var e=t._getContainer.apply(0,arguments),r=e&&e.container,i=e.x,n=e.y,a=e.width,s=e.height;if(!r)throw new Error("SVG container not found.");var o=v("svg"),l="overflow:hidden;",h;return i=i||0,n=n||0,a=a||512,s=s||342,v(o,{height:s,version:1.1,width:a,xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink"}),1==r?(o.style.cssText=l+"position:absolute;left:"+i+"px;top:"+n+"px",t._g.doc.body.appendChild(o),h=1):(o.style.cssText=l+"position:relative",r.firstChild?r.insertBefore(o,r.firstChild):r.appendChild(o)),r=new t._Paper,r.width=a,r.height=s,r.canvas=o,r.clear(),r._left=r._top=0,h&&(r.renderfix=function(){}),r.renderfix(),r},t._engine.setViewBox=function(t,e,r,i,n){u("raphael.setViewBox",this,this._viewBox,[t,e,r,i,n]);var a=this.getSize(),o=s(r/a.width,i/a.height),l=this.top,h=n?"xMidYMid meet":"xMinYMin",c,p;for(null==t?(this._vbSize&&(o=1),delete this._vbSize,c="0 0 "+this.width+f+this.height):(this._vbSize=o,c=t+f+e+f+r+f+i),v(this.canvas,{viewBox:c,preserveAspectRatio:h});o&&l;)p="stroke-width"in l.attrs?l.attrs["stroke-width"]:1,l.attr({"stroke-width":p}),l._.dirty=1,l._.dirtyT=1,l=l.prev;return this._viewBox=[t,e,r,i,!!n],this},t.prototype.renderfix=function(){var t=this.canvas,e=t.style,r;try{r=t.getScreenCTM()||t.createSVGMatrix()}catch(i){r=t.createSVGMatrix()}var n=-r.e%1,a=-r.f%1;(n||a)&&(n&&(this._left=(this._left+n)%1,e.left=this._left+"px"),a&&(this._top=(this._top+a)%1,e.top=this._top+"px"))},t.prototype.clear=function(){t.eve("raphael.clear",this);for(var e=this.canvas;e.firstChild;)e.removeChild(e.firstChild);this.bottom=this.top=null,(this.desc=v("desc")).appendChild(t._g.doc.createTextNode("Created with Raphaël "+t.version)),e.appendChild(this.desc),e.appendChild(this.defs=v("defs"))},t.prototype.remove=function(){u("raphael.remove",this),this.canvas.parentNode&&this.canvas.parentNode.removeChild(this.canvas);for(var e in this)this[e]="function"==typeof this[e]?t._removedFactory(e):null};var M=t.st;for(var N in E)E[e](N)&&!M[e](N)&&(M[N]=function(t){return function(){var e=arguments;return this.forEach(function(r){r[t].apply(r,e)})}}(N))}}.apply(e,i),!(void 0!==n&&(t.exports=n))},function(t,e,r){var i,n;i=[r(1)],n=function(t){if(!t||t.vml){var e="hasOwnProperty",r=String,i=parseFloat,n=Math,a=n.round,s=n.max,o=n.min,l=n.abs,h="fill",u=/[, ]+/,c=t.eve,f=" progid:DXImageTransform.Microsoft",p=" ",d="",g={M:"m",L:"l",C:"c",Z:"x",m:"t",l:"r",c:"v",z:"x"},v=/([clmz]),?([^clmz]*)/gi,x=/ progid:\S+Blur\([^\)]+\)/g,y=/-?[^,\s-]+/g,m="position:absolute;left:0;top:0;width:1px;height:1px;behavior:url(#default#VML)",b=21600,_={path:1,rect:1,image:1},w={circle:1,ellipse:1},k=function(e){var i=/[ahqstv]/gi,n=t._pathToAbsolute;if(r(e).match(i)&&(n=t._path2curve),i=/[clmz]/g,n==t._pathToAbsolute&&!r(e).match(i)){var s=r(e).replace(v,function(t,e,r){var i=[],n="m"==e.toLowerCase(),s=g[e];return r.replace(y,function(t){n&&2==i.length&&(s+=i+g["m"==e?"l":"L"],i=[]),i.push(a(t*b))}),s+i});return s}var o=n(e),l,h;s=[];for(var u=0,c=o.length;u<c;u++){l=o[u],h=o[u][0].toLowerCase(),"z"==h&&(h="x");for(var f=1,x=l.length;f<x;f++)h+=a(l[f]*b)+(f!=x-1?",":d);s.push(h)}return s.join(p)},B=function(e,r,i){var n=t.matrix();return n.rotate(-e,.5,.5),{dx:n.x(r,i),dy:n.y(r,i)}},C=function(t,e,r,i,n,a){var s=t._,o=t.matrix,u=s.fillpos,c=t.node,f=c.style,d=1,g="",v,x=b/e,y=b/r;if(f.visibility="hidden",e&&r){if(c.coordsize=l(x)+p+l(y),f.rotation=a*(e*r<0?-1:1),a){var m=B(a,i,n);i=m.dx,n=m.dy}if(e<0&&(g+="x"),r<0&&(g+=" y")&&(d=-1),f.flip=g,c.coordorigin=i*-x+p+n*-y,u||s.fillsize){var _=c.getElementsByTagName(h);_=_&&_[0],c.removeChild(_),u&&(m=B(a,o.x(u[0],u[1]),o.y(u[0],u[1])),_.position=m.dx*d+p+m.dy*d),s.fillsize&&(_.size=s.fillsize[0]*l(e)+p+s.fillsize[1]*l(r)),c.appendChild(_)}f.visibility="visible"}};t.toString=function(){return"Your browser doesn’t support SVG. Falling down to VML.\nYou are running Raphaël "+this.version};var S=function(t,e,i){for(var n=r(e).toLowerCase().split("-"),a=i?"end":"start",s=n.length,o="classic",l="medium",h="medium";s--;)switch(n[s]){case"block":case"classic":case"oval":case"diamond":case"open":case"none":o=n[s];break;case"wide":case"narrow":h=n[s];break;case"long":case"short":l=n[s]}var u=t.node.getElementsByTagName("stroke")[0];u[a+"arrow"]=o,u[a+"arrowlength"]=l,u[a+"arrowwidth"]=h},A=function(n,l){n.attrs=n.attrs||{};var c=n.node,f=n.attrs,g=c.style,v,x=_[n.type]&&(l.x!=f.x||l.y!=f.y||l.width!=f.width||l.height!=f.height||l.cx!=f.cx||l.cy!=f.cy||l.rx!=f.rx||l.ry!=f.ry||l.r!=f.r),y=w[n.type]&&(f.cx!=l.cx||f.cy!=l.cy||f.r!=l.r||f.rx!=l.rx||f.ry!=l.ry),m=n;for(var B in l)l[e](B)&&(f[B]=l[B]);if(x&&(f.path=t._getPath[n.type](n),n._.dirty=1),l.href&&(c.href=l.href),l.title&&(c.title=l.title),l.target&&(c.target=l.target),l.cursor&&(g.cursor=l.cursor),"blur"in l&&n.blur(l.blur),(l.path&&"path"==n.type||x)&&(c.path=k(~r(f.path).toLowerCase().indexOf("r")?t._pathToAbsolute(f.path):f.path),n._.dirty=1,"image"==n.type&&(n._.fillpos=[f.x,f.y],n._.fillsize=[f.width,f.height],C(n,1,1,0,0,0))),"transform"in l&&n.transform(l.transform),y){var A=+f.cx,E=+f.cy,M=+f.rx||+f.r||0,L=+f.ry||+f.r||0;c.path=t.format("ar{0},{1},{2},{3},{4},{1},{4},{1}x",a((A-M)*b),a((E-L)*b),a((A+M)*b),a((E+L)*b),a(A*b)),n._.dirty=1}if("clip-rect"in l){var z=r(l["clip-rect"]).split(u);if(4==z.length){z[2]=+z[2]+ +z[0],z[3]=+z[3]+ +z[1];var P=c.clipRect||t._g.doc.createElement("div"),F=P.style;F.clip=t.format("rect({1}px {2}px {3}px {0}px)",z),c.clipRect||(F.position="absolute",F.top=0,F.left=0,F.width=n.paper.width+"px",F.height=n.paper.height+"px",c.parentNode.insertBefore(P,c),P.appendChild(c),c.clipRect=P)}l["clip-rect"]||c.clipRect&&(c.clipRect.style.clip="auto")}if(n.textpath){var R=n.textpath.style;l.font&&(R.font=l.font),l["font-family"]&&(R.fontFamily='"'+l["font-family"].split(",")[0].replace(/^['"]+|['"]+$/g,d)+'"'),l["font-size"]&&(R.fontSize=l["font-size"]),l["font-weight"]&&(R.fontWeight=l["font-weight"]),l["font-style"]&&(R.fontStyle=l["font-style"])}if("arrow-start"in l&&S(m,l["arrow-start"]),"arrow-end"in l&&S(m,l["arrow-end"],1),null!=l.opacity||null!=l.fill||null!=l.src||null!=l.stroke||null!=l["stroke-width"]||null!=l["stroke-opacity"]||null!=l["fill-opacity"]||null!=l["stroke-dasharray"]||null!=l["stroke-miterlimit"]||null!=l["stroke-linejoin"]||null!=l["stroke-linecap"]){var j=c.getElementsByTagName(h),I=!1;if(j=j&&j[0],!j&&(I=j=N(h)),"image"==n.type&&l.src&&(j.src=l.src),l.fill&&(j.on=!0),null!=j.on&&"none"!=l.fill&&null!==l.fill||(j.on=!1),j.on&&l.fill){var q=r(l.fill).match(t._ISURL);if(q){j.parentNode==c&&c.removeChild(j),j.rotate=!0,j.src=q[1],j.type="tile";var D=n.getBBox(1);j.position=D.x+p+D.y,n._.fillpos=[D.x,D.y],t._preload(q[1],function(){n._.fillsize=[this.offsetWidth,this.offsetHeight]})}else j.color=t.getRGB(l.fill).hex,j.src=d,j.type="solid",t.getRGB(l.fill).error&&(m.type in{circle:1,ellipse:1}||"r"!=r(l.fill).charAt())&&T(m,l.fill,j)&&(f.fill="none",f.gradient=l.fill,j.rotate=!1)}if("fill-opacity"in l||"opacity"in l){var V=((+f["fill-opacity"]+1||2)-1)*((+f.opacity+1||2)-1)*((+t.getRGB(l.fill).o+1||2)-1);V=o(s(V,0),1),j.opacity=V,j.src&&(j.color="none")}c.appendChild(j);var O=c.getElementsByTagName("stroke")&&c.getElementsByTagName("stroke")[0],Y=!1;!O&&(Y=O=N("stroke")),(l.stroke&&"none"!=l.stroke||l["stroke-width"]||null!=l["stroke-opacity"]||l["stroke-dasharray"]||l["stroke-miterlimit"]||l["stroke-linejoin"]||l["stroke-linecap"])&&(O.on=!0),("none"==l.stroke||null===l.stroke||null==O.on||0==l.stroke||0==l["stroke-width"])&&(O.on=!1);var W=t.getRGB(l.stroke);O.on&&l.stroke&&(O.color=W.hex),V=((+f["stroke-opacity"]+1||2)-1)*((+f.opacity+1||2)-1)*((+W.o+1||2)-1);var G=.75*(i(l["stroke-width"])||1);if(V=o(s(V,0),1),null==l["stroke-width"]&&(G=f["stroke-width"]),l["stroke-width"]&&(O.weight=G),G&&G<1&&(V*=G)&&(O.weight=1),O.opacity=V,l["stroke-linejoin"]&&(O.joinstyle=l["stroke-linejoin"]||"miter"),O.miterlimit=l["stroke-miterlimit"]||8,l["stroke-linecap"]&&(O.endcap="butt"==l["stroke-linecap"]?"flat":"square"==l["stroke-linecap"]?"square":"round"),"stroke-dasharray"in l){var H={"-":"shortdash",".":"shortdot","-.":"shortdashdot","-..":"shortdashdotdot",". ":"dot","- ":"dash","--":"longdash","- .":"dashdot","--.":"longdashdot","--..":"longdashdotdot"};O.dashstyle=H[e](l["stroke-dasharray"])?H[l["stroke-dasharray"]]:d}Y&&c.appendChild(O)}if("text"==m.type){m.paper.canvas.style.display=d;var X=m.paper.span,U=100,$=f.font&&f.font.match(/\d+(?:\.\d*)?(?=px)/);g=X.style,f.font&&(g.font=f.font),f["font-family"]&&(g.fontFamily=f["font-family"]),f["font-weight"]&&(g.fontWeight=f["font-weight"]),f["font-style"]&&(g.fontStyle=f["font-style"]),$=i(f["font-size"]||$&&$[0])||10,g.fontSize=$*U+"px",m.textpath.string&&(X.innerHTML=r(m.textpath.string).replace(/</g,"<").replace(/&/g,"&").replace(/\n/g,"<br>"));var Z=X.getBoundingClientRect();m.W=f.w=(Z.right-Z.left)/U,m.H=f.h=(Z.bottom-Z.top)/U,m.X=f.x,m.Y=f.y+m.H/2,("x"in l||"y"in l)&&(m.path.v=t.format("m{0},{1}l{2},{1}",a(f.x*b),a(f.y*b),a(f.x*b)+1));for(var Q=["x","y","text","font","font-family","font-weight","font-style","font-size"],J=0,K=Q.length;J<K;J++)if(Q[J]in l){m._.dirty=1;break}switch(f["text-anchor"]){case"start":m.textpath.style["v-text-align"]="left",m.bbx=m.W/2;break;case"end":m.textpath.style["v-text-align"]="right",m.bbx=-m.W/2;break;default:m.textpath.style["v-text-align"]="center",m.bbx=0}m.textpath.style["v-text-kern"]=!0}},T=function(e,a,s){e.attrs=e.attrs||{};var o=e.attrs,l=Math.pow,h,u,c="linear",f=".5 .5";if(e.attrs.gradient=a,a=r(a).replace(t._radial_gradient,function(t,e,r){return c="radial",e&&r&&(e=i(e),r=i(r),l(e-.5,2)+l(r-.5,2)>.25&&(r=n.sqrt(.25-l(e-.5,2))*(2*(r>.5)-1)+.5),f=e+p+r),d}),a=a.split(/\s*\-\s*/),"linear"==c){var g=a.shift();if(g=-i(g),isNaN(g))return null}var v=t._parseDots(a);if(!v)return null;if(e=e.shape||e.node,v.length){e.removeChild(s),s.on=!0,s.method="none",s.color=v[0].color,s.color2=v[v.length-1].color;for(var x=[],y=0,m=v.length;y<m;y++)v[y].offset&&x.push(v[y].offset+p+v[y].color);s.colors=x.length?x.join():"0% "+s.color,"radial"==c?(s.type="gradientTitle",s.focus="100%",s.focussize="0 0",s.focusposition=f,s.angle=0):(s.type="gradient",s.angle=(270-g)%360),e.appendChild(s)}return 1},E=function(e,r){this[0]=this.node=e,e.raphael=!0,this.id=t._oid++,e.raphaelid=this.id,this.X=0,this.Y=0,this.attrs={},this.paper=r,this.matrix=t.matrix(),this._={transform:[],sx:1,sy:1,dx:0,dy:0,deg:0,dirty:1,dirtyT:1},!r.bottom&&(r.bottom=this),this.prev=r.top,r.top&&(r.top.next=this),r.top=this,this.next=null},M=t.el;E.prototype=M,M.constructor=E,M.transform=function(e){if(null==e)return this._.transform;var i=this.paper._viewBoxShift,n=i?"s"+[i.scale,i.scale]+"-1-1t"+[i.dx,i.dy]:d,a;i&&(a=e=r(e).replace(/\.{3}|\u2026/g,this._.transform||d)),t._extractTransform(this,n+e);var s=this.matrix.clone(),o=this.skew,l=this.node,h,u=~r(this.attrs.fill).indexOf("-"),c=!r(this.attrs.fill).indexOf("url(");if(s.translate(1,1),c||u||"image"==this.type)if(o.matrix="1 0 0 1",o.offset="0 0",h=s.split(),u&&h.noRotation||!h.isSimple){l.style.filter=s.toFilter();var f=this.getBBox(),g=this.getBBox(1),v=f.x-g.x,x=f.y-g.y;l.coordorigin=v*-b+p+x*-b,C(this,1,1,v,x,0)}else l.style.filter=d,C(this,h.scalex,h.scaley,h.dx,h.dy,h.rotate);else l.style.filter=d,o.matrix=r(s),o.offset=s.offset();return null!==a&&(this._.transform=a,t._extractTransform(this,a)),this},M.rotate=function(t,e,n){if(this.removed)return this;if(null!=t){if(t=r(t).split(u),t.length-1&&(e=i(t[1]),n=i(t[2])),t=i(t[0]),null==n&&(e=n),null==e||null==n){var a=this.getBBox(1);e=a.x+a.width/2,n=a.y+a.height/2}return this._.dirtyT=1,this.transform(this._.transform.concat([["r",t,e,n]])),this}},M.translate=function(t,e){return this.removed?this:(t=r(t).split(u),t.length-1&&(e=i(t[1])),t=i(t[0])||0,e=+e||0,this._.bbox&&(this._.bbox.x+=t,this._.bbox.y+=e),this.transform(this._.transform.concat([["t",t,e]])),this)},M.scale=function(t,e,n,a){if(this.removed)return this;if(t=r(t).split(u),t.length-1&&(e=i(t[1]),n=i(t[2]),a=i(t[3]),isNaN(n)&&(n=null),isNaN(a)&&(a=null)),t=i(t[0]),null==e&&(e=t),null==a&&(n=a),null==n||null==a)var s=this.getBBox(1);return n=null==n?s.x+s.width/2:n,a=null==a?s.y+s.height/2:a,this.transform(this._.transform.concat([["s",t,e,n,a]])),this._.dirtyT=1,this},M.hide=function(){return!this.removed&&(this.node.style.display="none"),this},M.show=function(){return!this.removed&&(this.node.style.display=d),this},M.auxGetBBox=t.el.getBBox,M.getBBox=function(){var t=this.auxGetBBox();if(this.paper&&this.paper._viewBoxShift){var e={},r=1/this.paper._viewBoxShift.scale;return e.x=t.x-this.paper._viewBoxShift.dx,e.x*=r,e.y=t.y-this.paper._viewBoxShift.dy,e.y*=r,e.width=t.width*r,e.height=t.height*r,e.x2=e.x+e.width,e.y2=e.y+e.height,e}return t},M._getBBox=function(){return this.removed?{}:{x:this.X+(this.bbx||0)-this.W/2,y:this.Y-this.H,width:this.W,height:this.H}},M.remove=function(){if(!this.removed&&this.node.parentNode){this.paper.__set__&&this.paper.__set__.exclude(this),t.eve.unbind("raphael.*.*."+this.id),t._tear(this,this.paper),this.node.parentNode.removeChild(this.node),this.shape&&this.shape.parentNode.removeChild(this.shape);for(var e in this)this[e]="function"==typeof this[e]?t._removedFactory(e):null;this.removed=!0}},M.attr=function(r,i){if(this.removed)return this;if(null==r){var n={};for(var a in this.attrs)this.attrs[e](a)&&(n[a]=this.attrs[a]);return n.gradient&&"none"==n.fill&&(n.fill=n.gradient)&&delete n.gradient,n.transform=this._.transform,n}if(null==i&&t.is(r,"string")){if(r==h&&"none"==this.attrs.fill&&this.attrs.gradient)return this.attrs.gradient;for(var s=r.split(u),o={},l=0,f=s.length;l<f;l++)r=s[l],r in this.attrs?o[r]=this.attrs[r]:t.is(this.paper.customAttributes[r],"function")?o[r]=this.paper.customAttributes[r].def:o[r]=t._availableAttrs[r];return f-1?o:o[s[0]]}if(this.attrs&&null==i&&t.is(r,"array")){for(o={},l=0,f=r.length;l<f;l++)o[r[l]]=this.attr(r[l]);return o}var p;null!=i&&(p={},p[r]=i),null==i&&t.is(r,"object")&&(p=r);for(var d in p)c("raphael.attr."+d+"."+this.id,this,p[d]);if(p){for(d in this.paper.customAttributes)if(this.paper.customAttributes[e](d)&&p[e](d)&&t.is(this.paper.customAttributes[d],"function")){var g=this.paper.customAttributes[d].apply(this,[].concat(p[d]));this.attrs[d]=p[d];for(var v in g)g[e](v)&&(p[v]=g[v])}p.text&&"text"==this.type&&(this.textpath.string=p.text),A(this,p)}return this},M.toFront=function(){return!this.removed&&this.node.parentNode.appendChild(this.node),this.paper&&this.paper.top!=this&&t._tofront(this,this.paper),this},M.toBack=function(){return this.removed?this:(this.node.parentNode.firstChild!=this.node&&(this.node.parentNode.insertBefore(this.node,this.node.parentNode.firstChild),t._toback(this,this.paper)),this)},M.insertAfter=function(e){return this.removed?this:(e.constructor==t.st.constructor&&(e=e[e.length-1]),e.node.nextSibling?e.node.parentNode.insertBefore(this.node,e.node.nextSibling):e.node.parentNode.appendChild(this.node),t._insertafter(this,e,this.paper),this)},M.insertBefore=function(e){return this.removed?this:(e.constructor==t.st.constructor&&(e=e[0]),e.node.parentNode.insertBefore(this.node,e.node),t._insertbefore(this,e,this.paper),this)},M.blur=function(e){var r=this.node.runtimeStyle,i=r.filter;return i=i.replace(x,d),0!==+e?(this.attrs.blur=e,r.filter=i+p+f+".Blur(pixelradius="+(+e||1.5)+")",r.margin=t.format("-{0}px 0 0 -{0}px",a(+e||1.5))):(r.filter=i,r.margin=0,delete this.attrs.blur),this},t._engine.path=function(t,e){var r=N("shape");r.style.cssText=m,r.coordsize=b+p+b,r.coordorigin=e.coordorigin;var i=new E(r,e),n={fill:"none",stroke:"#000"};t&&(n.path=t),i.type="path",i.path=[],i.Path=d,A(i,n),e.canvas&&e.canvas.appendChild(r);var a=N("skew");return a.on=!0,r.appendChild(a),i.skew=a,i.transform(d),i},t._engine.rect=function(e,r,i,n,a,s){var o=t._rectPath(r,i,n,a,s),l=e.path(o),h=l.attrs;return l.X=h.x=r,l.Y=h.y=i,l.W=h.width=n,l.H=h.height=a,h.r=s,h.path=o,l.type="rect",l},t._engine.ellipse=function(t,e,r,i,n){var a=t.path(),s=a.attrs;return a.X=e-i,a.Y=r-n,a.W=2*i,a.H=2*n,a.type="ellipse",A(a,{cx:e,cy:r,rx:i,ry:n}),a},t._engine.circle=function(t,e,r,i){var n=t.path(),a=n.attrs;return n.X=e-i,n.Y=r-i,n.W=n.H=2*i,n.type="circle",A(n,{cx:e,cy:r,r:i}),n},t._engine.image=function(e,r,i,n,a,s){var o=t._rectPath(i,n,a,s),l=e.path(o).attr({stroke:"none"}),u=l.attrs,c=l.node,f=c.getElementsByTagName(h)[0];return u.src=r,l.X=u.x=i,l.Y=u.y=n,l.W=u.width=a,l.H=u.height=s,u.path=o,l.type="image",f.parentNode==c&&c.removeChild(f),f.rotate=!0,f.src=r,f.type="tile",l._.fillpos=[i,n],l._.fillsize=[a,s],c.appendChild(f),C(l,1,1,0,0,0),l},t._engine.text=function(e,i,n,s){var o=N("shape"),l=N("path"),h=N("textpath");i=i||0,n=n||0,s=s||"",l.v=t.format("m{0},{1}l{2},{1}",a(i*b),a(n*b),a(i*b)+1),l.textpathok=!0,h.string=r(s),h.on=!0,o.style.cssText=m,o.coordsize=b+p+b,o.coordorigin="0 0";var u=new E(o,e),c={fill:"#000",stroke:"none",font:t._availableAttrs.font,text:s};u.shape=o,u.path=l,u.textpath=h,u.type="text",u.attrs.text=r(s),u.attrs.x=i,u.attrs.y=n,u.attrs.w=1,u.attrs.h=1,A(u,c),o.appendChild(h),o.appendChild(l),e.canvas.appendChild(o);var f=N("skew");return f.on=!0,o.appendChild(f),u.skew=f,u.transform(d),u},t._engine.setSize=function(e,r){var i=this.canvas.style;return this.width=e,this.height=r,e==+e&&(e+="px"),r==+r&&(r+="px"),i.width=e,i.height=r,i.clip="rect(0 "+e+" "+r+" 0)",this._viewBox&&t._engine.setViewBox.apply(this,this._viewBox),this},t._engine.setViewBox=function(e,r,i,n,a){t.eve("raphael.setViewBox",this,this._viewBox,[e,r,i,n,a]);var s=this.getSize(),o=s.width,l=s.height,h,u;return a&&(h=l/n,u=o/i,i*h<o&&(e-=(o-i*h)/2/h),n*u<l&&(r-=(l-n*u)/2/u)),this._viewBox=[e,r,i,n,!!a],this._viewBoxShift={dx:-e,dy:-r,scale:s},this.forEach(function(t){t.transform("...")}),this};var N;t._engine.initWin=function(t){var e=t.document;e.styleSheets.length<31?e.createStyleSheet().addRule(".rvml","behavior:url(#default#VML)"):e.styleSheets[0].addRule(".rvml","behavior:url(#default#VML)");try{!e.namespaces.rvml&&e.namespaces.add("rvml","urn:schemas-microsoft-com:vml"),N=function(t){return e.createElement("<rvml:"+t+' class="rvml">')}}catch(r){N=function(t){return e.createElement("<"+t+' xmlns="urn:schemas-microsoft.com:vml" class="rvml">')}}},t._engine.initWin(t._g.win),t._engine.create=function(){var e=t._getContainer.apply(0,arguments),r=e.container,i=e.height,n,a=e.width,s=e.x,o=e.y;if(!r)throw new Error("VML container not found.");var l=new t._Paper,h=l.canvas=t._g.doc.createElement("div"),u=h.style;return s=s||0,o=o||0,a=a||512,i=i||342,l.width=a,l.height=i,a==+a&&(a+="px"),i==+i&&(i+="px"),l.coordsize=1e3*b+p+1e3*b,l.coordorigin="0 0",l.span=t._g.doc.createElement("span"),l.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;",h.appendChild(l.span),u.cssText=t.format("top:0;left:0;width:{0};height:{1};display:inline-block;position:relative;clip:rect(0 {0} {1} 0);overflow:hidden",a,i),1==r?(t._g.doc.body.appendChild(h),u.left=s+"px",u.top=o+"px",u.position="absolute"):r.firstChild?r.insertBefore(h,r.firstChild):r.appendChild(h),l.renderfix=function(){},l},t.prototype.clear=function(){t.eve("raphael.clear",this),this.canvas.innerHTML=d,this.span=t._g.doc.createElement("span"),this.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;",this.canvas.appendChild(this.span),this.bottom=this.top=null},t.prototype.remove=function(){t.eve("raphael.remove",this),this.canvas.parentNode.removeChild(this.canvas);for(var e in this)this[e]="function"==typeof this[e]?t._removedFactory(e):null;return!0};var L=t.st;for(var z in M)M[e](z)&&!L[e](z)&&(L[z]=function(t){return function(){var e=arguments;return this.forEach(function(r){r[t].apply(r,e)})}}(z))}}.apply(e,i),!(void 0!==n&&(t.exports=n))}])});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
readme.txt
CHANGED
@@ -4,7 +4,7 @@
|
|
4 |
* Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=TD4AMD2D8EMZW
|
5 |
* Requires at least: 4.5
|
6 |
* Tested up to: 4.9
|
7 |
-
* Stable tag: 2.
|
8 |
* License: GPLv2 or later
|
9 |
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
@@ -86,6 +86,21 @@ A complete documentation is available in the [GitHub repository Wiki](https://gi
|
|
86 |
|
87 |
## Changelog ##
|
88 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
89 |
### 2.8.1 ###
|
90 |
* PHP 5.3 compatibility
|
91 |
* Bugfix where a spam trackback produced a fatal error
|
4 |
* Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=TD4AMD2D8EMZW
|
5 |
* Requires at least: 4.5
|
6 |
* Tested up to: 4.9
|
7 |
+
* Stable tag: 2.9.0
|
8 |
* License: GPLv2 or later
|
9 |
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
86 |
|
87 |
## Changelog ##
|
88 |
|
89 |
+
### 2.9.0 ###
|
90 |
+
* Introduction of coding standards.
|
91 |
+
* Switch to franc language detection API for the language check.
|
92 |
+
* Do not longer overwrite the IP address WordPress saves with the comment by using `pre_comment_user_ip`.
|
93 |
+
* Do not show "Trust commenters with a Gravatar" if the "Show Gravatar" option is not set.
|
94 |
+
* Skip the checks, when I ping myself.
|
95 |
+
* Fixes some wrong usages of the translation functions.
|
96 |
+
* Use the regular expressions check also for trackbacks.
|
97 |
+
* Add option to delete Antispam Bee related data when plugin gets deleted via the admin interface.
|
98 |
+
* Save a hashed + salted IP for every comment
|
99 |
+
* New check for incoming Trackbacks.
|
100 |
+
* Introduction of behat tests.
|
101 |
+
* Updates the used JavaScript library for the statistics widget.
|
102 |
+
* Bugfix in the "Comment form used outside of posts" option.
|
103 |
+
|
104 |
### 2.8.1 ###
|
105 |
* PHP 5.3 compatibility
|
106 |
* Bugfix where a spam trackback produced a fatal error
|