Easy Forms for MailChimp - Version 5.0.4

Version Description

  • Update SSL conditional in main plugin file
  • Added mcrypt module check, for API encryption
  • Conditionally loaded scripts and styles in admin ( prevent conflicts )
  • Included NONCE security checks on form submissions ( helps prevent CSRF and other attacks )
  • Added proper update task function to add missing settings to the options page ( prevents undefined variables for new settings )
  • Added missing styles to post page ( added missing icon to tinyMCE button )
  • Added missing styles to widget page
  • Adjusted Chimp Chatter activity time formatting to return correct time based on user time zone
  • New Feature : Real time updates to Account Activity ( utilizing the heartbeat API )
  • New Feature : Added account activity widget to dashboard ( with live updates using heartbeat API )
  • Added screenshot of admin dashboard account activity widget
Download this release

Release Info

Developer eherman24
Plugin Icon 128x128 Easy Forms for MailChimp
Version 5.0.4
Comparing to
See all releases

Code changes from version 5.0.3 to 5.0.4

classes/class.yksemeBase.php CHANGED
@@ -74,10 +74,23 @@ public function initialize()
74
  add_action('admin_print_styles', array(&$this, 'addStyles'));
75
  add_action('admin_print_scripts', array(&$this, 'addScripts'));
76
  add_action('admin_init', array( &$this, 'yks_easy_mc_plugin_activation_redirect' ) );
 
 
 
 
 
 
 
 
 
 
77
  // adding our custom content action
78
  // used to prevent other plugins from hooking
79
  // into the_content (such as jetpack sharedadddy, sharethis etc.)
80
  add_action( 'init', array( &$this, 'yks_mc_content' ), 1 );
 
 
 
81
  // tinymce buttons
82
  // only add filters and actions on wp 3.9 and above
83
  if ( get_bloginfo( 'version' ) >= '3.9' ) {
@@ -132,7 +145,7 @@ public function getOptionValue()
132
  'interest-group-label' => __('Select Your Area of Interest', 'yikes-inc-easy-mailchimp-extender'),
133
  'optIn-checkbox' => 'hide',
134
  'optIn-default-list' => array(),
135
- 'optin-checkbox-text' => 'SIGN ME UP!',
136
  'recaptcha-setting' => '0',
137
  'recaptcha-api-key' => '',
138
  'recaptcha-private-api-key' => '',
@@ -377,7 +390,7 @@ public function updateOptions($p)
377
  $this->optionVal['single-optin-message'] = $fd['single-optin-message'];
378
  $this->optionVal['double-optin-message'] = $fd['double-optin-message'];
379
  $this->optionVal['interest-group-label'] = $fd['interest-group-label'];
380
- $this->optionVal['yks-mailchimp-optIn-checkbox'] = $fd['yks-mailchimp-optIn-checkbox'];
381
  $this->optionVal['yks-mailchimp-optIn-default-list'] = isset($fd['yks-mailchimp-optIn-default-list']) ? $fd['yks-mailchimp-optIn-default-list'] : null; // if its set, else set to null <- fixes save form settings bug
382
  $this->optionVal['yks-mailchimp-optin-checkbox-text'] = $fd['yks-mailchimp-optin-checkbox-text'];
383
  update_option('api_validation', 'valid_api_key');
@@ -389,7 +402,7 @@ public function updateOptions($p)
389
  $this->optionVal['single-optin-message'] = $fd['single-optin-message'];
390
  $this->optionVal['double-optin-message'] = $fd['double-optin-message'];
391
  $this->optionVal['interest-group-label'] = $fd['interest-group-label'];
392
- $this->optionVal['yks-mailchimp-optIn-checkbox'] = $fd['yks-mailchimp-optIn-checkbox'];
393
  $this->optionVal['yks-mailchimp-optIn-default-list'] = isset($fd['yks-mailchimp-optIn-default-list']) ? $fd['yks-mailchimp-optIn-default-list'] : null; // if its set, else set to null <- fixes save form settings bug
394
  $this->optionVal['yks-mailchimp-optin-checkbox-text'] = $fd['yks-mailchimp-optin-checkbox-text'];
395
  update_option('api_validation', 'valid_api_key');
@@ -414,10 +427,10 @@ public function updateRecaptchaOptions($p)
414
  if(!empty($p['form_data']))
415
  {
416
  parse_str($p['form_data'], $fd);
417
- $this->optionVal['recaptcha-setting'] = $fd['yks-mailchimp-recaptcha-setting'];
418
- $this->optionVal['recaptcha-api-key'] = $fd['yks-mailchimp-recaptcha-api-key'];
419
- $this->optionVal['recaptcha-private-api-key'] = $fd['yks-mailchimp-recaptcha-private-api-key'];
420
- $this->optionVal['recaptcha-style'] = $fd['yks-mailchimp-recaptcha-style'];
421
  return update_option(YKSEME_OPTION, $this->optionVal);
422
  }
423
  return false;
@@ -1274,13 +1287,23 @@ public function yks_removeSubscriber($lid, $user_email) {
1274
  ****************************************************************************************************/
1275
  public function addStyles()
1276
  {
1277
- // Register Styles
1278
- wp_register_style('ykseme-css-base', YKSEME_URL.'css/style.ykseme.css', array(), '1.0.0', 'all');
1279
- wp_register_style('jquery-datatables-pagination', YKSEME_URL.'css/jquery.dataTables.css', array(), '1.0.0', 'all');
1280
- // Enqueue Styles
1281
- wp_enqueue_style('thickbox');
1282
- wp_enqueue_style('ykseme-css-base');
1283
- wp_enqueue_style('jquery-datatables-pagination');
 
 
 
 
 
 
 
 
 
 
1284
  }
1285
 
1286
  public function addStyles_frontend()
@@ -1295,22 +1318,33 @@ public function addStyles_frontend()
1295
  wp_enqueue_style('ykseme-animate-css');
1296
  }
1297
 
 
1298
  public function addScripts()
1299
  {
1300
- // Everything else
1301
- wp_enqueue_script('jquery-ui-core');
1302
- wp_enqueue_script('thickbox');
1303
- wp_enqueue_script('jquery-ui-sortable');
1304
- wp_enqueue_script('jquery-ui-tabs');
1305
- wp_enqueue_script('ykseme-base', YKSEME_URL.'js/script.ykseme.js', array('jquery'));
1306
- wp_enqueue_script('jquery-datatables-pagination', YKSEME_URL.'js/jquery.dataTables.js', array('jquery'));
1307
- wp_enqueue_script('jquery-highcharts-js', YKSEME_URL.'js/highcharts.js', array('jquery'));
1308
- wp_enqueue_script('jquery-highcharts-exporting-js', YKSEME_URL.'js/exporting.js', array('jquery'));
1309
- wp_enqueue_script('jquery-highcharts-3d-js', YKSEME_URL.'js/highcharts-3d.js', array('jquery'));
1310
 
1311
- wp_enqueue_script('jquery-highmaps-js', YKSEME_URL.'js/map.js', array('jquery'));
1312
- wp_enqueue_script('jquery-map-data-js', 'http://code.highcharts.com/mapdata/custom/world.js', array('jquery'));
1313
- wp_enqueue_script('jquery-highmaps-data-js', YKSEME_URL.'js/data.js', array('jquery'));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1314
  }
1315
 
1316
  // redirect the user to the settings page on initial activation
@@ -1457,13 +1491,14 @@ public function yks_resetPluginSettings() {
1457
  $this->optionVal['single-optin-message'] = __('Thank You for subscribing!', 'yikes-inc-easy-mailchimp-extender');
1458
  $this->optionVal['double-optin-message'] = __('Thank You for subscribing! Check your email for the confirmation message.', 'yikes-inc-easy-mailchimp-extender');
1459
  $this->optionVal['interest-group-label'] = '';
1460
- $this->optionVal['yks-mailchimp-optIn-checkbox'] = 'hide';
1461
  $this->optionVal['yks-mailchimp-optIn-default-list'] = array();
1462
  $this->optionVal['yks-mailchimp-optin-checkbox-text'] = 'SIGN ME UP!';
1463
- $this->optionVal['yks-mailchimp-recaptcha-setting'] = '0';
1464
- $this->optionVal['yks-mailchimp-recaptcha-api-key'] = '';
1465
- $this->optionVal['yks-mailchimp-recaptcha-private-api-key'] = '';
1466
- $this->optionVal['yks-mailchimp-recaptcha-style'] = 'default';
 
1467
  update_option('api_validation' , 'invalid_api_key');
1468
  // we need to unset the previously set up widgets
1469
  // and set up new erros if the API key doesn't exist
@@ -1568,7 +1603,7 @@ public function getUserProfileDetails()
1568
  public function getMailChimpChatter()
1569
  {
1570
  // Create and store our variables to pass to MailChimp
1571
- $apiKey = $_POST['api_key']; // api key
1572
  $api = new wpyksMCAPI($apiKey);
1573
  // try the call, catch any errors that may be thrown
1574
  try {
@@ -1581,6 +1616,25 @@ public function getMailChimpChatter()
1581
  wp_die();
1582
  }
1583
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1584
  // Make a call to MailChimp API to
1585
  // the lists/growth history method
1586
  // for statistics
@@ -2151,8 +2205,22 @@ public function addUserToMailchimp($p)
2151
  {
2152
  if(!empty($p['form_data']))
2153
  {
 
2154
  parse_str($p['form_data'], $fd);
2155
- if(!empty($fd['yks-mailchimp-list-id']))
 
 
 
 
 
 
 
 
 
 
 
 
 
2156
  {
2157
 
2158
  // if reCAPTCHA is enabled
@@ -2816,7 +2884,13 @@ public function getFrontendFormDisplay($list='', $submit_text)
2816
  $reCAPTCHA_image = recaptcha_get_html($reCAPTCHA_api_key);
2817
 
2818
  }
2819
- $num = 1;
 
 
 
 
 
 
2820
  foreach($list['fields'] as $field) : if($field['active'] == 1) :
2821
  // get field placeholders
2822
  $form_id = explode( '-', $field['id']);
@@ -2833,17 +2907,17 @@ public function getFrontendFormDisplay($list='', $submit_text)
2833
  });
2834
  </script>
2835
  <?php
2836
- if ($field['require'] == 1) // if the field is required (set in MailChimp), display the red required star
2837
- {
2838
- $reqindicator = " <span class='yks-required-label'>*</span>";
2839
- $reqlabel = " yks-mailchimpFormTableRowLabel-required";
2840
- }
2841
- else // else don't
2842
- {
2843
- $reqindicator = "";
2844
- $reqlabel = "";
2845
- }
2846
- ?>
2847
  <tr class="yks-mailchimpFormTableRow">
2848
  <td class="prompt yks-mailchimpFormTableRowLabel"><label class="prompt yks-mailchimpFormTableRowLabel<?php echo $reqlabel; ?>" for="<?php echo $field['id']; ?>"><?php echo $field['label']; ?><?php echo $reqindicator; ?></label>
2849
  <!-- run our function to generate the input fields for the form, passing in the field -->
@@ -2929,8 +3003,10 @@ public function getFrontendFormDisplay($list='', $submit_text)
2929
  $reCAPTCHA_api_key = $this->optionVal['recaptcha-api-key'];
2930
  $reCAPTCHA_image = recaptcha_get_html($reCAPTCHA_api_key);
2931
  }
2932
- $num = 1;
 
2933
  foreach($list['fields'] as $field) : if($field['active'] == 1) :
 
2934
  // get field placeholders
2935
  $form_id = explode( '-', $field['id']);
2936
  $field_placeholder_ = (isset($field['placeholder-'.$form_id[1].'-'.$num]) ? $field['placeholder-'.$form_id[1].'-'.$num] : '');
@@ -2946,17 +3022,17 @@ public function getFrontendFormDisplay($list='', $submit_text)
2946
  });
2947
  </script>
2948
  <?php
2949
- if ($field['require'] == 1) // if the field is required (set in MailChimp), display the red required star
2950
- {
2951
- $reqindicator = " <span class='yks-required-label'>*</span>";
2952
- $reqlabel = " yks-mailchimpFormDivRowLabel-required";
2953
- }
2954
- else // else don't
2955
- {
2956
- $reqindicator = "";
2957
- $reqlabel = "";
2958
- }
2959
- ?>
2960
  <div class="yks-mailchimpFormDivRow">
2961
  <label class="prompt yks-mailchimpFormDivRowLabel<?php echo $reqlabel; ?>" for="<?php echo $field['id']; ?>"><?php echo $field['label']; ?><?php echo $reqindicator; ?></label>
2962
  <div class="yks-mailchimpFormDivRowField">
@@ -2967,7 +3043,12 @@ public function getFrontendFormDisplay($list='', $submit_text)
2967
  <?php
2968
  $num++;
2969
  endif; endforeach;
2970
- ?>
 
 
 
 
 
2971
  <div class="yks-mailchimpFormDivRow">
2972
  <!-- run our function to generate the interest group fields for the form, passing in the form id -->
2973
  <?php $this->getInterestGroups($form_id[1]); ?>
@@ -3120,10 +3201,10 @@ private function andOrDropdown($name, $html, $sel)
3120
  ****************************************************************************************************/
3121
  public function runUpdateTasks()
3122
  {
3123
- $currentVersion = (!isset($this->optionVal['version']) || empty($this->optionVal['version']) ? '1.1.0' : $this->optionVal['version']);
3124
  $latestVersion = YKSEME_VERSION_CURRENT;
3125
  if($currentVersion < $latestVersion)
3126
- {
3127
  $updateFunction = 'runUpdateTasks_'.str_replace('.', '_', $currentVersion);
3128
  if(!method_exists($this, $updateFunction)) return false;
3129
  else
@@ -3232,6 +3313,39 @@ private function runUpdateTasks_1_3_0()
3232
  $this->optionVal['version'] = '2.2.1';
3233
  return true;
3234
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3235
 
3236
 
3237
  //
@@ -3587,6 +3701,489 @@ private function runUpdateTasks_1_3_0()
3587
  die(); // die to prevent data being sent over to MailChimp
3588
  }
3589
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3590
  }
3591
  }
3592
  ?>
74
  add_action('admin_print_styles', array(&$this, 'addStyles'));
75
  add_action('admin_print_scripts', array(&$this, 'addScripts'));
76
  add_action('admin_init', array( &$this, 'yks_easy_mc_plugin_activation_redirect' ) );
77
+
78
+ // custom Dashboard MailChimp Account Activity Widget
79
+ add_action( 'wp_dashboard_setup', array( &$this , 'yks_mc_add_chimp_chatter_dashboard_widget' ) );
80
+
81
+ // add a filter for our heartbeat response
82
+ // add_filter( 'heartbeat_received', array( &$this , 'yikes_mc_heartbeat_received' ) , 10, 2 );
83
+ add_filter('heartbeat_received', array( &$this , 'yks_mc_heartbeat_received' ) , 10, 2);
84
+ add_action("init", array( &$this , "yks_mc_heartbeat_init" ) );
85
+ add_filter( 'heartbeat_settings', array( &$this , 'yks_mc_tweak_heartbeat_settings') );
86
+
87
  // adding our custom content action
88
  // used to prevent other plugins from hooking
89
  // into the_content (such as jetpack sharedadddy, sharethis etc.)
90
  add_action( 'init', array( &$this, 'yks_mc_content' ), 1 );
91
+
92
+
93
+
94
  // tinymce buttons
95
  // only add filters and actions on wp 3.9 and above
96
  if ( get_bloginfo( 'version' ) >= '3.9' ) {
145
  'interest-group-label' => __('Select Your Area of Interest', 'yikes-inc-easy-mailchimp-extender'),
146
  'optIn-checkbox' => 'hide',
147
  'optIn-default-list' => array(),
148
+ 'yks-mailchimp-optin-checkbox-text' => 'SIGN ME UP!',
149
  'recaptcha-setting' => '0',
150
  'recaptcha-api-key' => '',
151
  'recaptcha-private-api-key' => '',
390
  $this->optionVal['single-optin-message'] = $fd['single-optin-message'];
391
  $this->optionVal['double-optin-message'] = $fd['double-optin-message'];
392
  $this->optionVal['interest-group-label'] = $fd['interest-group-label'];
393
+ $this->optionVal['optIn-checkbox'] = $fd['yks-mailchimp-optIn-checkbox'];
394
  $this->optionVal['yks-mailchimp-optIn-default-list'] = isset($fd['yks-mailchimp-optIn-default-list']) ? $fd['yks-mailchimp-optIn-default-list'] : null; // if its set, else set to null <- fixes save form settings bug
395
  $this->optionVal['yks-mailchimp-optin-checkbox-text'] = $fd['yks-mailchimp-optin-checkbox-text'];
396
  update_option('api_validation', 'valid_api_key');
402
  $this->optionVal['single-optin-message'] = $fd['single-optin-message'];
403
  $this->optionVal['double-optin-message'] = $fd['double-optin-message'];
404
  $this->optionVal['interest-group-label'] = $fd['interest-group-label'];
405
+ $this->optionVal['optIn-checkbox'] = $fd['yks-mailchimp-optIn-checkbox'];
406
  $this->optionVal['yks-mailchimp-optIn-default-list'] = isset($fd['yks-mailchimp-optIn-default-list']) ? $fd['yks-mailchimp-optIn-default-list'] : null; // if its set, else set to null <- fixes save form settings bug
407
  $this->optionVal['yks-mailchimp-optin-checkbox-text'] = $fd['yks-mailchimp-optin-checkbox-text'];
408
  update_option('api_validation', 'valid_api_key');
427
  if(!empty($p['form_data']))
428
  {
429
  parse_str($p['form_data'], $fd);
430
+ $this->optionVal['recaptcha-setting'] = isset($fd['yks-mailchimp-recaptcha-setting']) ? $fd['yks-mailchimp-recaptcha-setting'] : '0';
431
+ $this->optionVal['recaptcha-api-key'] = isset($fd['yks-mailchimp-recaptcha-api-key']) ? $fd['yks-mailchimp-recaptcha-api-key'] : '';
432
+ $this->optionVal['recaptcha-private-api-key'] = isset($fd['yks-mailchimp-recaptcha-private-api-key']) ? $fd['yks-mailchimp-recaptcha-private-api-key'] : '';
433
+ $this->optionVal['recaptcha-style'] = isset($fd['yks-mailchimp-recaptcha-style']) ? $fd['yks-mailchimp-recaptcha-style'] : 'default';
434
  return update_option(YKSEME_OPTION, $this->optionVal);
435
  }
436
  return false;
1287
  ****************************************************************************************************/
1288
  public function addStyles()
1289
  {
1290
+
1291
+ $screen_base = get_current_screen()->base;
1292
+
1293
+ if ( $screen_base == 'toplevel_page_yks-mailchimp-form' || $screen_base == 'mailchimp-forms_page_yks-mailchimp-my-mailchimp'
1294
+ || $screen_base == 'mailchimp-forms_page_yks-mailchimp-form-lists' || $screen_base == 'widgets' || $screen_base == 'post' ) {
1295
+ // Register Styles
1296
+ wp_register_style('ykseme-css-base', YKSEME_URL.'css/style.ykseme.css', array(), '1.0.0', 'all');
1297
+ wp_register_style('jquery-datatables-pagination', YKSEME_URL.'css/jquery.dataTables.css', array(), '1.0.0', 'all');
1298
+ // Enqueue Styles
1299
+ wp_enqueue_style('thickbox');
1300
+ wp_enqueue_style('ykseme-css-base');
1301
+ wp_enqueue_style('jquery-datatables-pagination');
1302
+ }
1303
+
1304
+ // just load the animate.css class on all admin pages
1305
+ wp_register_style('ykseme-animate-css', YKSEME_URL.'css/animate.css', array(), '1.0.0', 'all');
1306
+ wp_enqueue_style('ykseme-animate-css');
1307
  }
1308
 
1309
  public function addStyles_frontend()
1318
  wp_enqueue_style('ykseme-animate-css');
1319
  }
1320
 
1321
+
1322
  public function addScripts()
1323
  {
 
 
 
 
 
 
 
 
 
 
1324
 
1325
+ $screen_base = get_current_screen()->base;
1326
+
1327
+ if ( $screen_base == 'toplevel_page_yks-mailchimp-form' || $screen_base == 'mailchimp-forms_page_yks-mailchimp-my-mailchimp'
1328
+ || $screen_base == 'mailchimp-forms_page_yks-mailchimp-form-lists' ) {
1329
+ // Everything else
1330
+ // load our scripts in the dashboard
1331
+ wp_enqueue_script('jquery-ui-core');
1332
+ wp_enqueue_script('thickbox');
1333
+
1334
+ wp_enqueue_script('jquery-ui-sortable');
1335
+ wp_enqueue_script('jquery-ui-tabs');
1336
+ wp_enqueue_script('ykseme-base', YKSEME_URL.'js/script.ykseme.js', array('jquery'));
1337
+ wp_enqueue_script('jquery-datatables-pagination', YKSEME_URL.'js/jquery.dataTables.js', array('jquery'));
1338
+ wp_enqueue_script('jquery-highcharts-js', YKSEME_URL.'js/highcharts.js', array('jquery'));
1339
+ wp_enqueue_script('jquery-highcharts-exporting-js', YKSEME_URL.'js/exporting.js', array('jquery'));
1340
+ wp_enqueue_script('jquery-highcharts-3d-js', YKSEME_URL.'js/highcharts-3d.js', array('jquery'));
1341
+
1342
+ wp_enqueue_script('jquery-highmaps-js', YKSEME_URL.'js/map.js', array('jquery'));
1343
+ wp_enqueue_script('jquery-map-data-js', 'http://code.highcharts.com/mapdata/custom/world.js', array('jquery'));
1344
+ wp_enqueue_script('jquery-highmaps-data-js', YKSEME_URL.'js/data.js', array('jquery'));
1345
+ } else {
1346
+ return;
1347
+ }
1348
  }
1349
 
1350
  // redirect the user to the settings page on initial activation
1491
  $this->optionVal['single-optin-message'] = __('Thank You for subscribing!', 'yikes-inc-easy-mailchimp-extender');
1492
  $this->optionVal['double-optin-message'] = __('Thank You for subscribing! Check your email for the confirmation message.', 'yikes-inc-easy-mailchimp-extender');
1493
  $this->optionVal['interest-group-label'] = '';
1494
+ $this->optionVal['optIn-checkbox'] = 'hide';
1495
  $this->optionVal['yks-mailchimp-optIn-default-list'] = array();
1496
  $this->optionVal['yks-mailchimp-optin-checkbox-text'] = 'SIGN ME UP!';
1497
+ $this->optionVal['recaptcha-setting'] = '0';
1498
+ $this->optionVal['recaptcha-api-key'] = '';
1499
+ $this->optionVal['recaptcha-private-api-key'] = '';
1500
+ $this->optionVal['recaptcha-style'] = 'default';
1501
+ $this->optionVal['version'] = YKSEME_VERSION_CURRENT;
1502
  update_option('api_validation' , 'invalid_api_key');
1503
  // we need to unset the previously set up widgets
1504
  // and set up new erros if the API key doesn't exist
1603
  public function getMailChimpChatter()
1604
  {
1605
  // Create and store our variables to pass to MailChimp
1606
+ $apiKey = $this->optionVal['api-key']; // api key
1607
  $api = new wpyksMCAPI($apiKey);
1608
  // try the call, catch any errors that may be thrown
1609
  try {
1616
  wp_die();
1617
  }
1618
 
1619
+
1620
+ // Make a call to MailChimp API to validate the provided API key
1621
+ // calls the helper/chimp-chatter method, and returns Account Activity
1622
+ public function getMailChimpChatterForWidget()
1623
+ {
1624
+ // Create and store our variables to pass to MailChimp
1625
+ $apiKey = $this->optionVal['api-key']; // api key
1626
+ $api = new wpyksMCAPI($apiKey);
1627
+ // try the call, catch any errors that may be thrown
1628
+ try {
1629
+ $resp = $api->call('helper/chimp-chatter', array('apikey' => $apiKey));
1630
+ include_once YKSEME_PATH.'templates/mailChimpChatter-widget-template.php';
1631
+ } catch( Exception $e ) {
1632
+ echo '<strong>'.$e->getMessage().'</strong>';
1633
+ }
1634
+ // always die or it will always return 1
1635
+ wp_die();
1636
+ }
1637
+
1638
  // Make a call to MailChimp API to
1639
  // the lists/growth history method
1640
  // for statistics
2205
  {
2206
  if(!empty($p['form_data']))
2207
  {
2208
+
2209
  parse_str($p['form_data'], $fd);
2210
+
2211
+ // grab and store our nonce field
2212
+ // for security purposes
2213
+ $yks_mc_form_submission_nonce = $fd['_wpnonce'];
2214
+
2215
+ // cross check our nonce
2216
+ // passing in the action used when we created the nonce field
2217
+ // if the nonce does not match, we need to die()
2218
+ if ( !wp_verify_nonce( $yks_mc_form_submission_nonce , 'yks_mc_front_end_form_'.$fd['yks-mailchimp-list-id'] ) ) {
2219
+ die( __( 'Failed nonce security check. Please reload the page and submit this form again.' , 'yikes-inc-easy-mailchimp-extender' ) );
2220
+ }
2221
+
2222
+
2223
+ if( !empty( $fd['yks-mailchimp-list-id'] ) )
2224
  {
2225
 
2226
  // if reCAPTCHA is enabled
2884
  $reCAPTCHA_image = recaptcha_get_html($reCAPTCHA_api_key);
2885
 
2886
  }
2887
+ // add our nonce field for security purposes
2888
+ ?>
2889
+ <tr class="yks-mailchimpFormTableRow">
2890
+ <?php wp_nonce_field( 'yks_mc_front_end_form_'.$field['id'] ); ?>
2891
+ </tr>
2892
+ <?php
2893
+ $num = 1;
2894
  foreach($list['fields'] as $field) : if($field['active'] == 1) :
2895
  // get field placeholders
2896
  $form_id = explode( '-', $field['id']);
2907
  });
2908
  </script>
2909
  <?php
2910
+ if ($field['require'] == 1) // if the field is required (set in MailChimp), display the red required star
2911
+ {
2912
+ $reqindicator = " <span class='yks-required-label'>*</span>";
2913
+ $reqlabel = " yks-mailchimpFormTableRowLabel-required";
2914
+ }
2915
+ else // else don't
2916
+ {
2917
+ $reqindicator = "";
2918
+ $reqlabel = "";
2919
+ }
2920
+ ?>
2921
  <tr class="yks-mailchimpFormTableRow">
2922
  <td class="prompt yks-mailchimpFormTableRowLabel"><label class="prompt yks-mailchimpFormTableRowLabel<?php echo $reqlabel; ?>" for="<?php echo $field['id']; ?>"><?php echo $field['label']; ?><?php echo $reqindicator; ?></label>
2923
  <!-- run our function to generate the input fields for the form, passing in the field -->
3003
  $reCAPTCHA_api_key = $this->optionVal['recaptcha-api-key'];
3004
  $reCAPTCHA_image = recaptcha_get_html($reCAPTCHA_api_key);
3005
  }
3006
+ $num = 1;
3007
+
3008
  foreach($list['fields'] as $field) : if($field['active'] == 1) :
3009
+
3010
  // get field placeholders
3011
  $form_id = explode( '-', $field['id']);
3012
  $field_placeholder_ = (isset($field['placeholder-'.$form_id[1].'-'.$num]) ? $field['placeholder-'.$form_id[1].'-'.$num] : '');
3022
  });
3023
  </script>
3024
  <?php
3025
+ if ($field['require'] == 1) // if the field is required (set in MailChimp), display the red required star
3026
+ {
3027
+ $reqindicator = " <span class='yks-required-label'>*</span>";
3028
+ $reqlabel = " yks-mailchimpFormDivRowLabel-required";
3029
+ }
3030
+ else // else don't
3031
+ {
3032
+ $reqindicator = "";
3033
+ $reqlabel = "";
3034
+ }
3035
+ ?>
3036
  <div class="yks-mailchimpFormDivRow">
3037
  <label class="prompt yks-mailchimpFormDivRowLabel<?php echo $reqlabel; ?>" for="<?php echo $field['id']; ?>"><?php echo $field['label']; ?><?php echo $reqindicator; ?></label>
3038
  <div class="yks-mailchimpFormDivRowField">
3043
  <?php
3044
  $num++;
3045
  endif; endforeach;
3046
+ ?>
3047
+ <!-- add our nonce field for security purposes -->
3048
+ <div class="yks-mailchimpFormDivRow">
3049
+ <?php wp_nonce_field( 'yks_mc_front_end_form_'.$form_id[1] ); ?>
3050
+ </div>
3051
+
3052
  <div class="yks-mailchimpFormDivRow">
3053
  <!-- run our function to generate the interest group fields for the form, passing in the form id -->
3054
  <?php $this->getInterestGroups($form_id[1]); ?>
3201
  ****************************************************************************************************/
3202
  public function runUpdateTasks()
3203
  {
3204
+ $currentVersion = (!isset($this->optionVal['version']) || empty($this->optionVal['version']) ? '5.0.3' : $this->optionVal['version']);
3205
  $latestVersion = YKSEME_VERSION_CURRENT;
3206
  if($currentVersion < $latestVersion)
3207
+ {
3208
  $updateFunction = 'runUpdateTasks_'.str_replace('.', '_', $currentVersion);
3209
  if(!method_exists($this, $updateFunction)) return false;
3210
  else
3313
  $this->optionVal['version'] = '2.2.1';
3314
  return true;
3315
  }
3316
+
3317
+ /**
3318
+ * This update needs to pull in all of the custom form
3319
+ * data for each of the lists, unfortunately it has to replace
3320
+ * just about all of the data with the new schema. We also
3321
+ * add in the flavor key (for table/div usage)
3322
+ *
3323
+ * 4.3 => 5.0.4
3324
+ */
3325
+ private function runUpdateTasks_4_3()
3326
+ {
3327
+
3328
+ if ( !isset( $this->optionVal['recaptcha-setting'] ) ) {
3329
+ $this->optionVal['recaptcha-setting'] = '0';
3330
+ }
3331
+
3332
+ if ( !isset( $this->optionVal['recaptcha-api-key'] ) ) {
3333
+ $this->optionVal['recaptcha-api-key'] = '';
3334
+ }
3335
+
3336
+ if ( !isset( $this->optionVal['recaptcha-private-api-key'] ) ) {
3337
+ $this->optionVal['recaptcha-private-api-key'] = '';
3338
+ }
3339
+
3340
+ if ( !isset( $this->optionVal['recaptcha-style'] ) ) {
3341
+ $this->optionVal['recaptcha-style'] = 'default';
3342
+ }
3343
+
3344
+ $this->optionVal['version'] = '5.0.4';
3345
+
3346
+ return true;
3347
+
3348
+ }
3349
 
3350
 
3351
  //
3701
  die(); // die to prevent data being sent over to MailChimp
3702
  }
3703
 
3704
+
3705
+
3706
+
3707
+ /****************************************************************************************
3708
+ *
3709
+ * Begin Heartbeat API Code
3710
+ * - Used on the Account Activity page for lilve updates
3711
+ *
3712
+ ****************************************************************************************/
3713
+
3714
+ /*
3715
+ Client-side code. First we enqueue the Heartbeat API and our Javascript.
3716
+
3717
+ Our Javascript is then setup to always send the message 'marco' to the server.
3718
+ If a message comes back, the Javascript logs it (polo) to console.
3719
+ */
3720
+
3721
+ //enqueue heartbeat.js and our Javascript
3722
+ function yks_mc_heartbeat_init()
3723
+ {
3724
+ /*
3725
+ //Add your conditionals here so this runs on the pages you want, e.g.
3726
+ if(is_admin())
3727
+ return; //don't run this in the admin
3728
+ */
3729
+
3730
+ //enqueue the Heartbeat API
3731
+ wp_enqueue_script('heartbeat');
3732
+
3733
+ //load our Javascript in the footer
3734
+ add_action("admin_print_footer_scripts", array( &$this ,"yks_mc_heartbeat_admin_footer" ) );
3735
+ }
3736
+
3737
+
3738
+ //our Javascript to send/process from the client side
3739
+ function yks_mc_heartbeat_admin_footer()
3740
+ {
3741
+
3742
+ $request_uri = "$_SERVER[REQUEST_URI]";
3743
+ global $pagenow;
3744
+
3745
+ // Only proceed if on the the my mailchimp page
3746
+ // and the chimp-chatter tab
3747
+ if( 'admin.php?page=yks-mailchimp-my-mailchimp&tab=chimp_chatter' != basename($request_uri) && 'index.php' != $pagenow )
3748
+ return;
3749
+
3750
+ ?>
3751
+ <script>
3752
+ jQuery(document).ready(function() {
3753
+
3754
+ //hook into heartbeat-send: client will send the message 'marco' in the 'client' var inside the data array
3755
+ jQuery(document).on('heartbeat-send', function(e, data) {
3756
+ <?php if( 'index.php' == $pagenow ) { ?>
3757
+ // send some data
3758
+ // to begin the ajax
3759
+ data['yks_mc_chimp_chatter_heartbeat'] = 'get_chimp_chatter_widget_data';
3760
+ <?php } else { ?>
3761
+ // send some data
3762
+ // to begin the ajax
3763
+ data['yks_mc_chimp_chatter_heartbeat'] = 'get_chimp_chatter_data';
3764
+ <?php } ?>
3765
+ });
3766
+
3767
+ //hook into heartbeat-tick: client looks for a 'server' var in the data array and logs it to console
3768
+ jQuery(document).on('heartbeat-tick', function(e, data) {
3769
+
3770
+ // pass our API key along
3771
+ var apiKey = '<?php echo $this->optionVal['api-key']; ?>';
3772
+
3773
+ // store datacenter value, from end of api key
3774
+ var dataCenter = apiKey.substr(apiKey.indexOf("-") + 1);
3775
+
3776
+ if(data['yks_mc_chimp_chatter_data'] == 'Get MailChimp Chatter Data' ) {
3777
+
3778
+ // update the chimp chatter div with new info
3779
+ // heartbeat api
3780
+ jQuery.ajax({
3781
+ type: 'POST',
3782
+ url: ajaxurl,
3783
+ data: {
3784
+ action: 'yks_mailchimp_form',
3785
+ form_action: 'yks_get_chimp_chatter',
3786
+ api_key: apiKey,
3787
+ data_center: dataCenter
3788
+ },
3789
+ dataType: 'html',
3790
+ success: function(response) {
3791
+
3792
+ // store the new response, in the new response hidden div, for comparison
3793
+ jQuery('#new_chimp_chatter_response').html(response);
3794
+
3795
+ // wrap our emails in the hidden new response with
3796
+ // <a> to match the original response
3797
+ jQuery("#new_chimp_chatter_response").find("td:nth-child(4)").each(function() {
3798
+ jQuery(this).filter(function(){
3799
+ var html = jQuery(this).html();
3800
+ // regex email pattern,
3801
+ // to wrap our emails in a link
3802
+ var emailPattern = /[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}/g;
3803
+ var matched_str = jQuery(this).html().match(emailPattern);
3804
+ var matched_str = jQuery(this).html().match(emailPattern);
3805
+ if(matched_str){
3806
+ var text = jQuery(this).html();
3807
+ jQuery.each(matched_str, function(index, value){
3808
+ text = text.replace(value,"<a href='mailto:"+value+"'>"+value+"</a>");
3809
+ });
3810
+ jQuery(this).html(text);
3811
+ return jQuery(this)
3812
+ }
3813
+ });
3814
+ });
3815
+
3816
+ // checking if the response is new...
3817
+ if ( jQuery('#new_chimp_chatter_response').html() == jQuery('#original_chimp_chatter_response').html() ) {
3818
+
3819
+ console.log('the data is the same. no action taken.');
3820
+
3821
+ } else {
3822
+
3823
+ // remove the new stars
3824
+ jQuery('.fadeInDown').each(function() {
3825
+ jQuery(this).removeClass('animated').removeClass('fadeInDown').removeClass('new-chatter-item');
3826
+ });
3827
+
3828
+ // count the new chatter items ( divide by 2 , for the spacer tr )
3829
+ var new_chatter_count = parseInt( jQuery('#new_chimp_chatter_response').find('.chatter-table-row').length / 2 );
3830
+ // count the original chatter items ( divide by 2 , for the spacer tr )
3831
+ var original_chatter_count = parseInt( jQuery('#original_chimp_chatter_response').find('.chatter-table-row').length / 2 );
3832
+
3833
+ // calculate the number of new items
3834
+ var number_of_new_items = parseInt( new_chatter_count - original_chatter_count );
3835
+
3836
+ // test the count of items,
3837
+ // console.log('The original count is : '+original_chatter_count);
3838
+ // console.log('The new count is : '+new_chatter_count);
3839
+
3840
+
3841
+ // give feedback that new data was found
3842
+ console.log('new mailchimp chatter data found. Re-populating....');
3843
+
3844
+ // store the new response, in the original response
3845
+ // field for comparison when heartbeat runs again
3846
+ jQuery('#original_chimp_chatter_response').html(response);
3847
+
3848
+
3849
+ // up next -- growl notifications!
3850
+ // for real time subscribes/unsubscribes/shares notifications all over the dashboard
3851
+
3852
+
3853
+ var i = 1;
3854
+
3855
+ function new_chatter_loop_and_append() {
3856
+
3857
+ setInterval(function() {
3858
+
3859
+ // this code is executed every 5 seconds:
3860
+ // animate the new items in
3861
+ // .....badass....
3862
+ while (i <= number_of_new_items) {
3863
+
3864
+ var item_to_append = jQuery('#new_chimp_chatter_response').find('.chatter-content-row:nth-child('+i+')');
3865
+
3866
+ jQuery('.mailChimpChatterDiv').find('.chatter-table-row:first-child').before('<tr class="chatter-table-row chatter-spacer-row"><td>&nbsp;</td></tr>');
3867
+ jQuery('.mailChimpChatterDiv').find('.chatter-table-row:first-child').before( item_to_append.addClass('fadeInDown animated new-chatter-item') );
3868
+
3869
+ i++;
3870
+
3871
+ }
3872
+
3873
+ }, 6000 );
3874
+
3875
+ }
3876
+
3877
+ // loop over our new items and append them to the current page
3878
+ new_chatter_loop_and_append();
3879
+
3880
+
3881
+
3882
+ // re-apply the link wrapping the new items
3883
+ // so the new items match the old items
3884
+ jQuery("#original_chimp_chatter_response table#yks-admin-chimp-chatter .chatter-table-row td:nth-child(4)").each(function() {
3885
+ jQuery(this).filter(function(){
3886
+ var html = jQuery(this).html();
3887
+ // regex email pattern,
3888
+ // to wrap our emails in a link
3889
+ var emailPattern = /[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}/g;
3890
+ var matched_str = jQuery(this).html().match(emailPattern);
3891
+ var matched_str = jQuery(this).html().match(emailPattern);
3892
+ if(matched_str){
3893
+ var text = jQuery(this).html();
3894
+ jQuery.each(matched_str, function(index, value){
3895
+ text = text.replace(value,"<a href='mailto:"+value+"'>"+value+"</a>");
3896
+ });
3897
+ jQuery(this).html(text);
3898
+ return jQuery(this)
3899
+ }
3900
+ });
3901
+ });
3902
+
3903
+ // give some feedback
3904
+ console.log( "Populated the chimpchatter div with new content." );
3905
+
3906
+ }
3907
+
3908
+ // let user know heartbeat is running
3909
+ console.log('heartbeat found...');
3910
+
3911
+ },
3912
+ error: function(response) {
3913
+ // do nothing here,
3914
+ // incase we inturrupt it with a page change
3915
+ }
3916
+
3917
+ });
3918
+
3919
+ // Run this on the Dashboard, to re-populate the
3920
+ // mailchimp activity widget!
3921
+ } else if(data['yks_mc_chimp_chatter_data'] == 'Get MailChimp Chatter Widget Data' ) {
3922
+
3923
+
3924
+ // update the chimp chatter div with new info
3925
+ // heartbeat api
3926
+ jQuery.ajax({
3927
+ type: 'POST',
3928
+ url: ajaxurl,
3929
+ data: {
3930
+ action: 'yks_mailchimp_form',
3931
+ form_action: 'yks_get_widget_chimp_chatter',
3932
+ api_key: apiKey,
3933
+ data_center: dataCenter
3934
+ },
3935
+ dataType: 'html',
3936
+ success: function(response) {
3937
+
3938
+
3939
+ // store the new response, in the new response hidden div, for comparison
3940
+ jQuery('#new_chimp_chatter_response').html(response);
3941
+
3942
+
3943
+ // checking if the response is new...
3944
+ if ( jQuery('#new_chimp_chatter_response').html() == jQuery('#original_chimp_chatter_response').html() ) {
3945
+
3946
+ console.log('the data is the same. no action taken.');
3947
+
3948
+ } else {
3949
+
3950
+ // remove the new stars
3951
+ jQuery('.fadeInDown').each(function() {
3952
+ jQuery(this).removeClass('animated').removeClass('fadeInDown').removeClass('new-chatter-item');
3953
+ });
3954
+
3955
+ // count the new chatter items ( divide by 2 , for the spacer tr )
3956
+ var new_chatter_count = parseInt( jQuery('#new_chimp_chatter_response').find('.chatter-content-row').length );
3957
+ // count the original chatter items ( divide by 2 , for the spacer tr )
3958
+ var original_chatter_count = parseInt( jQuery('#original_chimp_chatter_response').find('.chatter-content-row').length );
3959
+
3960
+ // calculate the number of new items
3961
+ var number_of_new_items = parseInt( new_chatter_count - original_chatter_count );
3962
+
3963
+ // test the count of items,
3964
+ // console.log('The original count is : '+original_chatter_count);
3965
+ // console.log('The new count is : '+new_chatter_count);
3966
+
3967
+
3968
+ // give feedback that new data was found
3969
+ console.log('new mailchimp chatter data found. Re-populating....');
3970
+
3971
+ // store the new response, in the original response
3972
+ // field for comparison when heartbeat runs again
3973
+ jQuery('#original_chimp_chatter_response').html(response);
3974
+
3975
+
3976
+ // up next -- growl notifications!
3977
+ // for real time subscribes/unsubscribes/shares notifications all over the dashboard
3978
+
3979
+
3980
+ var i = 1;
3981
+
3982
+ function new_chatter_loop_and_append() {
3983
+
3984
+ setInterval(function() {
3985
+
3986
+ // this code is executed every 5 seconds:
3987
+ // animate the new items in
3988
+ // .....badass....
3989
+ while (i <= number_of_new_items) {
3990
+
3991
+ var item_to_append = jQuery('#new_chimp_chatter_response').find('.chatter-content-row:nth-child('+i+')');
3992
+
3993
+ jQuery('.yks_mailChimp_Chatter').find('.chatter-table-row:first-child').before( item_to_append.addClass('fadeInDown animated new-chatter-item') );
3994
+
3995
+ i++;
3996
+
3997
+ }
3998
+
3999
+ }, 6000 );
4000
+
4001
+ }
4002
+
4003
+ // loop over our new items and append them to the current page
4004
+ new_chatter_loop_and_append();
4005
+
4006
+
4007
+
4008
+ // re-apply the link wrapping the new items
4009
+ // so the new items match the old items
4010
+ jQuery("#original_chimp_chatter_response table#yks-admin-chimp-chatter .chatter-table-row td:nth-child(4)").each(function() {
4011
+ jQuery(this).filter(function(){
4012
+ var html = jQuery(this).html();
4013
+ // regex email pattern,
4014
+ // to wrap our emails in a link
4015
+ var emailPattern = /[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}/g;
4016
+ var matched_str = jQuery(this).html().match(emailPattern);
4017
+ var matched_str = jQuery(this).html().match(emailPattern);
4018
+ if(matched_str){
4019
+ var text = jQuery(this).html();
4020
+ jQuery.each(matched_str, function(index, value){
4021
+ text = text.replace(value,"<a href='mailto:"+value+"'>"+value+"</a>");
4022
+ });
4023
+ jQuery(this).html(text);
4024
+ return jQuery(this)
4025
+ }
4026
+ });
4027
+ });
4028
+
4029
+ // give some feedback
4030
+ console.log( "Populated the chimpchatter div with new content." );
4031
+
4032
+ }
4033
+
4034
+ // let user know heartbeat is running
4035
+ console.log('heartbeat found...');
4036
+
4037
+ },
4038
+ error: function(response) {
4039
+ // do nothing here,
4040
+ // incase we inturrupt it with a page change
4041
+ }
4042
+
4043
+ });
4044
+
4045
+
4046
+ }
4047
+
4048
+
4049
+ });
4050
+
4051
+ //hook into heartbeat-error: in case of error, let's log some stuff
4052
+ jQuery(document).on('heartbeat-error', function(e, jqXHR, textStatus, error) {
4053
+ console.log('<< BEGIN ERROR');
4054
+ console.log(textStatus);
4055
+ console.log(error);
4056
+ console.log('END ERROR >>');
4057
+ });
4058
+
4059
+ });
4060
+ </script>
4061
+ <?php
4062
+ }
4063
+
4064
+
4065
+ /*
4066
+ Our server-side code.
4067
+ ------------------------------
4068
+ This hooks into the heartbeat_received filter.
4069
+ It checks for a key 'client' in the data array. If it is set to 'get_chimp_chatter_data',
4070
+ a key 'server' is set to 'Get MailChimp Chatter Data' in the response array.
4071
+ */
4072
+ function yks_mc_heartbeat_received($response, $data) {
4073
+
4074
+ // if the client returns get chimp chatter data, popluate
4075
+ // the response with some data
4076
+ if( $data['yks_mc_chimp_chatter_heartbeat'] == 'get_chimp_chatter_data' ) {
4077
+ // populate the response with something
4078
+ $response['yks_mc_chimp_chatter_data'] = 'Get MailChimp Chatter Data';
4079
+ } else if ( $data['yks_mc_chimp_chatter_heartbeat'] == 'get_chimp_chatter_widget_data' ) {
4080
+ $response['yks_mc_chimp_chatter_data'] = 'Get MailChimp Chatter Widget Data';
4081
+ }
4082
+
4083
+ return $response;
4084
+
4085
+ }
4086
+
4087
+ /** Change Default HeartBeat API Pulse Time */
4088
+ function yks_mc_tweak_heartbeat_settings( $settings ) {
4089
+ $settings['interval'] = 15; //Anything between 15-60
4090
+ return $settings;
4091
+ }
4092
+
4093
+
4094
+
4095
+
4096
+ /*******************************************************
4097
+ Custom Dashboard MailChimp Account Activity Widget
4098
+ ********************************************************/
4099
+ /**
4100
+ * Add a widget to the dashboard.
4101
+ *
4102
+ * This function is hooked into the 'wp_dashboard_setup' action below.
4103
+ */
4104
+ function yks_mc_add_chimp_chatter_dashboard_widget() {
4105
+
4106
+ wp_add_dashboard_widget(
4107
+ 'yks_mc_account_activity_widget', // Widget slug.
4108
+ 'MailChimp Account Activity', // Title.
4109
+ array( &$this , 'yks_mc_chimp_chatter_dashboard_widget_function' ) // Display function.
4110
+ );
4111
+
4112
+ }
4113
+
4114
+
4115
+ /**
4116
+ * Create the function to output the contents of our Dashboard Widget.
4117
+ */
4118
+ function yks_mc_chimp_chatter_dashboard_widget_function() {
4119
+ // Trigger our ajax call, and then include our ChimpChatter template
4120
+ // to properly populate the data
4121
+ ?>
4122
+ <!--
4123
+ apply our styles on initial page load,
4124
+ this is for adding our icon to the widget title,
4125
+ for a little branding action
4126
+ -->
4127
+ <style>
4128
+ #yks_mc_account_activity_widget > h3 > span:before {
4129
+ content: url('<?php echo plugins_url(); ?>/yikes-inc-easy-mailchimp-extender/images/yikes_logo_widget_icon.png');
4130
+ width:33px;
4131
+ float:left;
4132
+ height:10px;
4133
+ margin: -3px 10px 0 0px;
4134
+ }
4135
+ </style>
4136
+ <script type="text/javascript">
4137
+ jQuery(document).ready(function() {
4138
+ // add the preloader to the widget
4139
+ jQuery('#yks-admin-chimp-chatter').html();
4140
+
4141
+ var apiKey = '<?php echo $this->optionVal['api-key']; ?>';
4142
+ jQuery('#yks-mailchimp-api-key').val();
4143
+ // store datacenter value, from end of api key
4144
+ var dataCenter = apiKey.substr(apiKey.indexOf("-") + 1);
4145
+
4146
+ // post the data to our MailChimp Chatter function inside of lib.ajax.php
4147
+ jQuery.ajax({
4148
+ type: 'POST',
4149
+ url: ajaxurl,
4150
+ data: {
4151
+ action: 'yks_mailchimp_form',
4152
+ form_action: 'yks_get_widget_chimp_chatter',
4153
+ api_key: apiKey,
4154
+ data_center: dataCenter
4155
+ },
4156
+ dataType: 'html',
4157
+ success: function(response) {
4158
+
4159
+ // populate the original chimp chatter input with our original response
4160
+ jQuery('#yks_mc_account_activity_widget').find('.inside').html(response);
4161
+
4162
+ // create hidden input fields to store our returned data for comparison
4163
+ // create our new chimp chatter response field
4164
+ jQuery('#yks-admin-chimp-chatter').before('<div style="display:none;" id="new_chimp_chatter_response"></div>');
4165
+ // create our original chimp chatter response
4166
+ jQuery('#yks-admin-chimp-chatter').before('<div style="display:none;" id="original_chimp_chatter_response"></div>');
4167
+
4168
+ // populate the visible chimp chatter div with the content
4169
+ // on original page load
4170
+ jQuery('#yks-admin-chimp-chatter').not('#new_chimp_chatter_response').html(response);
4171
+ jQuery('#original_chimp_chatter_response').html(response);
4172
+
4173
+
4174
+ },
4175
+ error: function(response) {
4176
+ jQuery('.nav-tab-wrapper').after('<p style="width:100%;text-align:center;margin:1em 0;">There was an error processing your request. Please try again. If this error persists, please open a support thread <a href="https://github.com/yikesinc/yikes-inc-easy-mailchimp-extender" title="Yikes Inc Easy MailChimp GitHub Issue Tracker" target="_blank">here</a>.</p>');
4177
+ }
4178
+ });
4179
+ });
4180
+ </script>
4181
+ <?php
4182
+
4183
+ ?><img style="display:block;margin:0 auto;margin-top:2em;margin-bottom:1em;" class="mailChimp_get_subscribers_preloader" src="<?php echo admin_url().'/images/wpspin_light.gif'; ?>" alt="preloader" ><?php
4184
+ }
4185
+
4186
+
4187
  }
4188
  }
4189
  ?>
css/style.ykseme.css CHANGED
@@ -1075,24 +1075,8 @@ textarea#debug_loaded_apache_modules {
1075
  width:100%
1076
  }
1077
  }
1078
-
1079
- /* Chimp Chatter Triangle on Container */
1080
- .chimp-chatter-message:after, .chimp-chatter-message:before {
1081
- left:-19px;
1082
- top:42%;
1083
- border:solid transparent;
1084
- content:" ";
1085
- height:0;
1086
- width:0;
1087
- position:absolute;
1088
- pointer-events:none;
1089
- border-right-color:#fff;
1090
- border-width:10px
1091
- }
1092
 
1093
- .chimp-chatter-message:before {
1094
- border-right-color: #e0e0e0;
1095
- }
1096
 
1097
  @media screen and (max-width:60em) {
1098
  .chimp-chatter-message:after, .chimp-chatter-message:before {
@@ -1521,6 +1505,17 @@ textarea#debug_loaded_apache_modules {
1521
  }
1522
 
1523
 
 
 
 
 
 
 
 
 
 
 
 
1524
  /* Print Stylesheet */
1525
  /**************************/
1526
 
@@ -1555,4 +1550,6 @@ textarea#debug_loaded_apache_modules {
1555
  }
1556
 
1557
 
 
 
1558
  }
1075
  width:100%
1076
  }
1077
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1078
 
1079
+
 
 
1080
 
1081
  @media screen and (max-width:60em) {
1082
  .chimp-chatter-message:after, .chimp-chatter-message:before {
1505
  }
1506
 
1507
 
1508
+ /***** New Chimp Chatter Item + Star *****/
1509
+ .new-chatter-item td:first-child:before {
1510
+ content: "\f155";
1511
+ font-family: "dashicons";
1512
+ left: 0;
1513
+ font-size: 2em;
1514
+ color: rgb(248, 226, 58);
1515
+ }
1516
+
1517
+
1518
+
1519
  /* Print Stylesheet */
1520
  /**************************/
1521
 
1550
  }
1551
 
1552
 
1553
+
1554
+
1555
  }
images/Thumbs.db CHANGED
Binary file
images/reCAPTCHA/{reCAPTCHA_Sample_white.png → reCAPTCHA_Sample_White.png} RENAMED
File without changes
js/jquery.1.7.1.min.js ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ /*! jQuery v1.7.1 jquery.com | jquery.org/license */
2
+ (function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cv(a){if(!ck[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cl||(cl=c.createElement("iframe"),cl.frameBorder=cl.width=cl.height=0),b.appendChild(cl);if(!cm||!cl.createElement)cm=(cl.contentWindow||cl.contentDocument).document,cm.write((c.compatMode==="CSS1Compat"?"<!doctype html>":"")+"<html><body>"),cm.close();d=cm.createElement(a),cm.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cl)}ck[a]=e}return ck[a]}function cu(a,b){var c={};f.each(cq.concat.apply([],cq.slice(0,b)),function(){c[this]=a});return c}function ct(){cr=b}function cs(){setTimeout(ct,0);return cr=f.now()}function cj(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ci(){try{return new a.XMLHttpRequest}catch(b){}}function cc(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g<i;g++){if(g===1)for(h in a.converters)typeof h=="string"&&(e[h.toLowerCase()]=a.converters[h]);l=k,k=d[g];if(k==="*")k=l;else if(l!=="*"&&l!==k){m=l+" "+k,n=e[m]||e["* "+k];if(!n){p=b;for(o in e){j=o.split(" ");if(j[0]===l||j[0]==="*"){p=e[j[1]+" "+k];if(p){o=e[o],o===!0?n=p:p===!0&&(n=o);break}}}}!n&&!p&&f.error("No conversion from "+m.replace(" "," to ")),n!==!0&&(c=n?n(c):p(o(c)))}}return c}function cb(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=a.mimeType||c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function ca(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bE.test(a)?d(a,e):ca(a+"["+(typeof e=="object"||f.isArray(e)?b:"")+"]",e,c,d)});else if(!c&&b!=null&&typeof b=="object")for(var e in b)ca(a+"["+e+"]",b[e],c,d);else d(a,b)}function b_(a,c){var d,e,g=f.ajaxSettings.flatOptions||{};for(d in c)c[d]!==b&&((g[d]?a:e||(e={}))[d]=c[d]);e&&f.extend(!0,a,e)}function b$(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bT,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l=="string"&&(!k||g[l]?l=b:(c.dataTypes.unshift(l),l=b$(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=b$(a,c,d,e,"*",g));return l}function bZ(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f.isFunction(c)){var d=b.toLowerCase().split(bP),e=0,g=d.length,h,i,j;for(;e<g;e++)h=d[e],j=/^\+/.test(h),j&&(h=h.substr(1)||"*"),i=a[h]=a[h]||[],i[j?"unshift":"push"](c)}}}function bC(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=b==="width"?bx:by,g=0,h=e.length;if(d>0){if(c!=="border")for(;g<h;g++)c||(d-=parseFloat(f.css(a,"padding"+e[g]))||0),c==="margin"?d+=parseFloat(f.css(a,c+e[g]))||0:d-=parseFloat(f.css(a,"border"+e[g]+"Width"))||0;return d+"px"}d=bz(a,b,b);if(d<0||d==null)d=a.style[b]||0;d=parseFloat(d)||0;if(c)for(;g<h;g++)d+=parseFloat(f.css(a,"padding"+e[g]))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+e[g]+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+e[g]))||0);return d+"px"}function bp(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bf,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bo(a){var b=c.createElement("div");bh.appendChild(b),b.innerHTML=a.outerHTML;return b.firstChild}function bn(a){var b=(a.nodeName||"").toLowerCase();b==="input"?bm(a):b!=="script"&&typeof a.getElementsByTagName!="undefined"&&f.grep(a.getElementsByTagName("input"),bm)}function bm(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bl(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bk(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(f.expando)}}function bj(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c,d,e,g=f._data(a),h=f._data(b,g),i=g.events;if(i){delete h.handle,h.events={};for(c in i)for(d=0,e=i[c].length;d<e;d++)f.event.add(b,c+(i[c][d].namespace?".":"")+i[c][d].namespace,i[c][d],i[c][d].data)}h.data&&(h.data=f.extend({},h.data))}}function bi(a,b){return f.nodeName(a,"table")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function U(a){var b=V.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}function T(a,b,c){b=b||0;if(f.isFunction(b))return f.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return f.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=f.grep(a,function(a){return a.nodeType===1});if(O.test(b))return f.filter(b,d,!c);b=f.filter(b,d)}return f.grep(a,function(a,d){return f.inArray(a,b)>=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parseFloat(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c<d;c++)b[a[c]]=!0;return b}var c=a.document,d=a.navigator,e=a.location,f=function(){function J(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(J,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j<k;j++)if((a=arguments[j])!=null)for(c in a){d=i[c],f=a[c];if(i===f)continue;l&&f&&(e.isPlainObject(f)||(g=e.isArray(f)))?(g?(g=!1,h=d&&e.isArray(d)?d:[]):h=d&&e.isPlainObject(d)?d:{},i[c]=e.extend(l,h,f)):f!==b&&(i[c]=f)}return i},e.extend({noConflict:function(b){a.$===e&&(a.$=g),b&&a.jQuery===e&&(a.jQuery=f);return e},isReady:!1,readyWait:1,holdReady:function(a){a?e.readyWait++:e.ready(!0)},ready:function(a){if(a===!0&&!--e.readyWait||a!==!0&&!e.isReady){if(!c.body)return setTimeout(e.ready,1);e.isReady=!0;if(a!==!0&&--e.readyWait>0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g<h;)if(c.apply(a[g++],d)===!1)break}else if(i){for(f in a)if(c.call(a[f],f,a[f])===!1)break}else for(;g<h;)if(c.call(a[g],g,a[g++])===!1)break;return a},trim:G?function(a){return a==null?"":G.call(a)}:function(a){return a==null?"":(a+"").replace(k,"").replace(l,"")},makeArray:function(a,b){var c=b||[];if(a!=null){var d=e.type(a);a.length==null||d==="string"||d==="function"||d==="regexp"||e.isWindow(a)?E.call(c,a):e.merge(c,a)}return c},inArray:function(a,b,c){var d;if(b){if(H)return H.call(b,a,c);d=b.length,c=c?c<0?Math.max(0,d+c):c:0;for(;c<d;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,c){var d=a.length,e=0;if(typeof c.length=="number")for(var f=c.length;e<f;e++)a[d++]=c[e];else while(c[e]!==b)a[d++]=c[e++];a.length=d;return a},grep:function(a,b,c){var d=[],e;c=!!c;for(var f=0,g=a.length;f<g;f++)e=!!b(a[f],f),c!==e&&d.push(a[f]);return d},map:function(a,c,d){var f,g,h=[],i=0,j=a.length,k=a instanceof e||j!==b&&typeof j=="number"&&(j>0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i<j;i++)f=c(a[i],i,d),f!=null&&(h[h.length]=f);else for(g in a)f=c(a[g],g,d),f!=null&&(h[h.length]=f);return h.concat.apply([],h)},guid:1,proxy:function(a,c){if(typeof c=="string"){var d=a[c];c=a,a=d}if(!e.isFunction(a))return b;var f=F.call(arguments,2),g=function(){return a.apply(c,f.concat(F.call(arguments)))};g.guid=a.guid=a.guid||g.guid||e.guid++;return g},access:function(a,c,d,f,g,h){var i=a.length;if(typeof c=="object"){for(var j in c)e.access(a,j,c[j],f,g,d);return a}if(d!==b){f=!h&&f&&e.isFunction(d);for(var k=0;k<i;k++)g(a[k],c,f?d.call(a[k],k,g(a[k],c)):d,h);return a}return i?g(a[0],c):b},now:function(){return(new Date).getTime()},uaMatch:function(a){a=a.toLowerCase();var b=r.exec(a)||s.exec(a)||t.exec(a)||a.indexOf("compatible")<0&&u.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},sub:function(){function a(b,c){return new a.fn.init(b,c)}e.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function(d,f){f&&f instanceof e&&!(f instanceof a)&&(f=a(f));return e.fn.init.call(this,d,f,b)},a.fn.init.prototype=a.fn;var b=a(c);return a},browser:{}}),e.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){I["[object "+b+"]"]=b.toLowerCase()}),z=e.uaMatch(y),z.browser&&(e.browser[z.browser]=!0,e.browser.version=z.version),e.browser.webkit&&(e.browser.safari=!0),j.test(" ")&&(k=/^[\s\xA0]+/,l=/[\s\xA0]+$/),h=e(c),c.addEventListener?B=function(){c.removeEventListener("DOMContentLoaded",B,!1),e.ready()}:c.attachEvent&&(B=function(){c.readyState==="complete"&&(c.detachEvent("onreadystatechange",B),e.ready())});return e}(),g={};f.Callbacks=function(a){a=a?g[a]||h(a):{};var c=[],d=[],e,i,j,k,l,m=function(b){var d,e,g,h,i;for(d=0,e=b.length;d<e;d++)g=b[d],h=f.type(g),h==="array"?m(g):h==="function"&&(!a.unique||!o.has(g))&&c.push(g)},n=function(b,f){f=f||[],e=!a.memory||[b,f],i=!0,l=j||0,j=0,k=c.length;for(;c&&l<k;l++)if(c[l].apply(b,f)===!1&&a.stopOnFalse){e=!0;break}i=!1,c&&(a.once?e===!0?o.disable():c=[]:d&&d.length&&(e=d.shift(),o.fireWith(e[0],e[1])))},o={add:function(){if(c){var a=c.length;m(arguments),i?k=c.length:e&&e!==!0&&(j=a,n(e[0],e[1]))}return this},remove:function(){if(c){var b=arguments,d=0,e=b.length;for(;d<e;d++)for(var f=0;f<c.length;f++)if(b[d]===c[f]){i&&f<=k&&(k--,f<=l&&l--),c.splice(f--,1);if(a.unique)break}}return this},has:function(a){if(c){var b=0,d=c.length;for(;b<d;b++)if(a===c[b])return!0}return!1},empty:function(){c=[];return this},disable:function(){c=d=e=b;return this},disabled:function(){return!c},lock:function(){d=b,(!e||e===!0)&&o.disable();return this},locked:function(){return!d},fireWith:function(b,c){d&&(i?a.once||d.push([b,c]):(!a.once||!e)&&n(b,c));return this},fire:function(){o.fireWith(this,arguments);return this},fired:function(){return!!e}};return o};var i=[].slice;f.extend({Deferred:function(a){var b=f.Callbacks("once memory"),c=f.Callbacks("once memory"),d=f.Callbacks("memory"),e="pending",g={resolve:b,reject:c,notify:d},h={done:b.add,fail:c.add,progress:d.add,state:function(){return e},isResolved:b.fired,isRejected:c.fired,then:function(a,b,c){i.done(a).fail(b).progress(c);return this},always:function(){i.done.apply(i,arguments).fail.apply(i,arguments);return this},pipe:function(a,b,c){return f.Deferred(function(d){f.each({done:[a,"resolve"],fail:[b,"reject"],progress:[c,"notify"]},function(a,b){var c=b[0],e=b[1],g;f.isFunction(c)?i[a](function(){g=c.apply(this,arguments),g&&f.isFunction(g.promise)?g.promise().then(d.resolve,d.reject,d.notify):d[e+"With"](this===i?d:this,[g])}):i[a](d[e])})}).promise()},promise:function(a){if(a==null)a=h;else for(var b in h)a[b]=h[b];return a}},i=h.promise({}),j;for(j in g)i[j]=g[j].fire,i[j+"With"]=g[j].fireWith;i.done(function(){e="resolved"},c.disable,d.lock).fail(function(){e="rejected"},b.disable,d.lock),a&&a.call(i,i);return i},when:function(a){function m(a){return function(b){e[a]=arguments.length>1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c<d;c++)b[c]&&b[c].promise&&f.isFunction(b[c].promise)?b[c].promise().then(l(c),j.reject,m(c)):--g;g||j.resolveWith(j,b)}else j!==a&&j.resolveWith(j,d?[a]:[]);return k}}),f.support=function(){var b,d,e,g,h,i,j,k,l,m,n,o,p,q=c.createElement("div"),r=c.documentElement;q.setAttribute("className","t"),q.innerHTML=" <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>",d=q.getElementsByTagName("*"),e=q.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=q.getElementsByTagName("input")[0],b={leadingWhitespace:q.firstChild.nodeType===3,tbody:!q.getElementsByTagName("tbody").length,htmlSerialize:!!q.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:q.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav></:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete q.test}catch(s){b.deleteExpando=!1}!q.addEventListener&&q.attachEvent&&q.fireEvent&&(q.attachEvent("onclick",function(){b.noCloneEvent=!1}),q.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),q.appendChild(i),k=c.createDocumentFragment(),k.appendChild(q.lastChild),b.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,k.removeChild(i),k.appendChild(q),q.innerHTML="",a.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",q.style.width="2px",q.appendChild(j),b.reliableMarginRight=(parseInt((a.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(q.attachEvent)for(o in{submit:1,change:1,focusin:1})n="on"+o,p=n in q,p||(q.setAttribute(n,"return;"),p=typeof q[n]=="function"),b[o+"Bubbles"]=p;k.removeChild(q),k=g=h=j=q=i=null,f(function(){var a,d,e,g,h,i,j,k,m,n,o,r=c.getElementsByTagName("body")[0];!r||(j=1,k="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",m="visibility:hidden;border:0;",n="style='"+k+"border:5px solid #000;padding:0;'",o="<div "+n+"><div></div></div>"+"<table "+n+" cellpadding='0' cellspacing='0'>"+"<tr><td></td></tr></table>",a=c.createElement("div"),a.style.cssText=m+"width:0;height:0;position:static;top:0;margin-top:"+j+"px",r.insertBefore(a,r.firstChild),q=c.createElement("div"),a.appendChild(q),q.innerHTML="<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>",l=q.getElementsByTagName("td"),p=l[0].offsetHeight===0,l[0].style.display="",l[1].style.display="none",b.reliableHiddenOffsets=p&&l[0].offsetHeight===0,q.innerHTML="",q.style.width=q.style.paddingLeft="1px",f.boxModel=b.boxModel=q.offsetWidth===2,typeof q.style.zoom!="undefined"&&(q.style.display="inline",q.style.zoom=1,b.inlineBlockNeedsLayout=q.offsetWidth===2,q.style.display="",q.innerHTML="<div style='width:4px;'></div>",b.shrinkWrapBlocks=q.offsetWidth!==2),q.style.cssText=k+m,q.innerHTML=o,d=q.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,i={doesNotAddBorder:e.offsetTop!==5,doesAddBorderForTableAndCells:h.offsetTop===5},e.style.position="fixed",e.style.top="20px",i.fixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",i.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,i.doesNotIncludeMarginInBodyOffset=r.offsetTop!==j,r.removeChild(a),q=a=null,f.extend(b,i))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e<g;e++)delete d[b[e]];if(!(c?m:f.isEmptyObject)(d))return}}if(!c){delete j[k].data;if(!m(j[k]))return}f.support.deleteExpando||!j.setInterval?delete j[k]:j[k]=null,i&&(f.support.deleteExpando?delete a[h]:a.removeAttribute?a.removeAttribute(h):a[h]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d,e,g,h=null;if(typeof a=="undefined"){if(this.length){h=f.data(this[0]);if(this[0].nodeType===1&&!f._data(this[0],"parsedAttrs")){e=this[0].attributes;for(var i=0,j=e.length;i<j;i++)g=e[i].name,g.indexOf("data-")===0&&(g=f.camelCase(g.substring(5)),l(this[0],g,h[g]));f._data(this[0],"parsedAttrs",!0)}}return h}if(typeof a=="object")return this.each(function(){f.data(this,a)});d=a.split("."),d[1]=d[1]?"."+d[1]:"";if(c===b){h=this.triggerHandler("getData"+d[1]+"!",[d[0]]),h===b&&this.length&&(h=f.data(this[0],a),h=l(this[0],a,h));return h===b&&d[1]?this.data(d[0]):h}return this.each(function(){var b=f(this),e=[d[0],c];b.triggerHandler("setData"+d[1]+"!",e),f.data(this,a,c),b.triggerHandler("changeData"+d[1]+"!",e)})},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,b){a&&(b=(b||"fx")+"mark",f._data(a,b,(f._data(a,b)||0)+1))},_unmark:function(a,b,c){a!==!0&&(c=b,b=a,a=!1);if(b){c=c||"fx";var d=c+"mark",e=a?0:(f._data(b,d)||1)-1;e?f._data(b,d,e):(f.removeData(b,d,!0),n(b,c,"mark"))}},queue:function(a,b,c){var d;if(a){b=(b||"fx")+"queue",d=f._data(a,b),c&&(!d||f.isArray(c)?d=f._data(a,b,f.makeArray(c)):d.push(c));return d||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e={};d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),f._data(a,b+".run",e),d.call(a,function(){f.dequeue(a,b)},e)),c.length||(f.removeData(a,b+"queue "+b+".run",!0),n(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){typeof a!="string"&&(c=a,a="fx");if(c===b)return f.queue(this[0],a);return this.each(function(){var b=f.queue(this,a,c);a==="fx"&&b[0]!=="inprogress"&&f.dequeue(this,a)})},dequeue:function(a){return this.each(function(){f.dequeue(this,a)})},delay:function(a,b){a=f.fx?f.fx.speeds[a]||a:a,b=b||"fx";return this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){function m(){--h||d.resolveWith(e,[e])}typeof a!="string"&&(c=a,a=b),a=a||"fx";var d=f.Deferred(),e=this,g=e.length,h=1,i=a+"defer",j=a+"queue",k=a+"mark",l;while(g--)if(l=f.data(e[g],i,b,!0)||(f.data(e[g],j,b,!0)||f.data(e[g],k,b,!0))&&f.data(e[g],i,f.Callbacks("once memory"),!0))h++,l.add(m);m();return d.promise()}});var o=/[\n\t\r]/g,p=/\s+/,q=/\r/g,r=/^(?:button|input)$/i,s=/^(?:button|input|object|select|textarea)$/i,t=/^a(?:rea)?$/i,u=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,v=f.support.getSetAttribute,w,x,y;f.fn.extend({attr:function(a,b){return f.access(this,a,b,!0,f.attr)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,a,b,!0,f.prop)},removeProp:function(a){a=f.propFix[a]||a;return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,g,h,i;if(f.isFunction(a))return this.each(function(b){f(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(p);for(c=0,d=this.length;c<d;c++){e=this[c];if(e.nodeType===1)if(!e.className&&b.length===1)e.className=a;else{g=" "+e.className+" ";for(h=0,i=b.length;h<i;h++)~g.indexOf(" "+b[h]+" ")||(g+=b[h]+" ");e.className=f.trim(g)}}}return this},removeClass:function(a){var c,d,e,g,h,i,j;if(f.isFunction(a))return this.each(function(b){f(this).removeClass(a.call(this,b,this.className))});if(a&&typeof a=="string"||a===b){c=(a||"").split(p);for(d=0,e=this.length;d<e;d++){g=this[d];if(g.nodeType===1&&g.className)if(a){h=(" "+g.className+" ").replace(o," ");for(i=0,j=c.length;i<j;i++)h=h.replace(" "+c[i]+" "," ");g.className=f.trim(h)}else g.className=""}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";if(f.isFunction(a))return this.each(function(c){f(this).toggleClass(a.call(this,c,this.className,b),b)});return this.each(function(){if(c==="string"){var e,g=0,h=f(this),i=b,j=a.split(p);while(e=j[g++])i=d?i:!h.hasClass(e),h[i?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&f._data(this,"__className__",this.className),this.className=this.className||a===!1?"":f._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ",c=0,d=this.length;for(;c<d;c++)if(this[c].nodeType===1&&(" "+this[c].className+" ").replace(o," ").indexOf(b)>-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c<d;c++){e=i[c];if(e.selected&&(f.support.optDisabled?!e.disabled:e.getAttribute("disabled")===null)&&(!e.parentNode.disabled||!f.nodeName(e.parentNode,"optgroup"))){b=f(e).val();if(j)return b;h.push(b)}}if(j&&!h.length&&i.length)return f(i[g]).val();return h},set:function(a,b){var c=f.makeArray(b);f(a).find("option").each(function(){this.selected=f.inArray(f(this).val(),c)>=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;h<g;h++)e=d[h],e&&(c=f.propFix[e]||e,f.attr(a,e,""),a.removeAttribute(v?e:c),u.test(e)&&c in a&&(a[c]=!1))}},attrHooks:{type:{set:function(a,b){if(r.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},value:{get:function(a,b){if(w&&f.nodeName(a,"button"))return w.get(a,b);return b in a?a.value:null},set:function(a,b,c){if(w&&f.nodeName(a,"button"))return w.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e,g,h,i=a.nodeType;if(!!a&&i!==3&&i!==8&&i!==2){h=i!==1||!f.isXMLDoc(a),h&&(c=f.propFix[c]||c,g=f.propHooks[c]);return d!==b?g&&"set"in g&&(e=g.set(a,d,c))!==b?e:a[c]=d:g&&"get"in g&&(e=g.get(a,c))!==null?e:a[c]}},propHooks:{tabIndex:{get:function(a){var c=a.getAttributeNode("tabindex");return c&&c.specified?parseInt(c.value,10):s.test(a.nodeName)||t.test(a.nodeName)&&a.href?0:b}}}}),f.attrHooks.tabindex=f.propHooks.tabIndex,x={get:function(a,c){var d,e=f.prop(a,c);return e===!0||typeof e!="boolean"&&(d=a.getAttributeNode(c))&&d.nodeValue!==!1?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase()));return c}},v||(y={name:!0,id:!0},w=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&(y[c]?d.nodeValue!=="":d.specified)?d.nodeValue:b},set:function(a,b,d){var e=a.getAttributeNode(d);e||(e=c.createAttribute(d),a.setAttributeNode(e));return e.nodeValue=b+""}},f.attrHooks.tabindex.set=w.set,f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})}),f.attrHooks.contenteditable={get:w.get,set:function(a,b,c){b===""&&(b="false"),w.set(a,b,c)}}),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex);return null}})),f.support.enctype||(f.propFix.enctype="encoding"),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/\bhover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")};
3
+ f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k<c.length;k++){l=A.exec(c[k])||[],m=l[1],n=(l[2]||"").split(".").sort(),s=f.event.special[m]||{},m=(g?s.delegateType:s.bindType)||m,s=f.event.special[m]||{},o=f.extend({type:m,origType:l[1],data:e,handler:d,guid:d.guid,selector:g,quick:G(g),namespace:n.join(".")},p),r=j[m];if(!r){r=j[m]=[],r.delegateCount=0;if(!s.setup||s.setup.call(a,e,n,i)===!1)a.addEventListener?a.addEventListener(m,i,!1):a.attachEvent&&a.attachEvent("on"+m,i)}s.add&&(s.add.call(a,o),o.handler.guid||(o.handler.guid=d.guid)),g?r.splice(r.delegateCount++,0,o):r.push(o),f.event.global[m]=!0}a=null}},global:{},remove:function(a,b,c,d,e){var g=f.hasData(a)&&f._data(a),h,i,j,k,l,m,n,o,p,q,r,s;if(!!g&&!!(o=g.events)){b=f.trim(I(b||"")).split(" ");for(h=0;h<b.length;h++){i=A.exec(b[h])||[],j=k=i[1],l=i[2];if(!j){for(j in o)f.event.remove(a,j+b[h],c,d,!0);continue}p=f.event.special[j]||{},j=(d?p.delegateType:p.bindType)||j,r=o[j]||[],m=r.length,l=l?new RegExp("(^|\\.)"+l.split(".").sort().join("\\.(?:.*\\.)?")+"(\\.|$)"):null;for(n=0;n<r.length;n++)s=r[n],(e||k===s.origType)&&(!c||c.guid===s.guid)&&(!l||l.test(s.namespace))&&(!d||d===s.selector||d==="**"&&s.selector)&&(r.splice(n--,1),s.selector&&r.delegateCount--,p.remove&&p.remove.call(a,s));r.length===0&&m!==r.length&&((!p.teardown||p.teardown.call(a,l)===!1)&&f.removeEvent(a,j,g.handle),delete o[j])}f.isEmptyObject(o)&&(q=g.handle,q&&(q.elem=null),f.removeData(a,["events","handle"],!0))}},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,e,g){if(!e||e.nodeType!==3&&e.nodeType!==8){var h=c.type||c,i=[],j,k,l,m,n,o,p,q,r,s;if(E.test(h+f.event.triggered))return;h.indexOf("!")>=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;l<r.length&&!c.isPropagationStopped();l++)m=r[l][0],c.type=r[l][1],q=(f._data(m,"events")||{})[c.type]&&f._data(m,"handle"),q&&q.apply(m,d),q=o&&m[o],q&&f.acceptData(m)&&q.apply(m,d)===!1&&c.preventDefault();c.type=h,!g&&!c.isDefaultPrevented()&&(!p._default||p._default.apply(e.ownerDocument,d)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)&&o&&e[h]&&(h!=="focus"&&h!=="blur"||c.target.offsetWidth!==0)&&!f.isWindow(e)&&(n=e[o],n&&(e[o]=null),f.event.triggered=h,e[h](),f.event.triggered=b,n&&(e[o]=n));return c.result}},dispatch:function(c){c=f.event.fix(c||a.event);var d=(f._data(this,"events")||{})[c.type]||[],e=d.delegateCount,g=[].slice.call(arguments,0),h=!c.exclusive&&!c.namespace,i=[],j,k,l,m,n,o,p,q,r,s,t;g[0]=c,c.delegateTarget=this;if(e&&!c.target.disabled&&(!c.button||c.type!=="click")){m=f(this),m.context=this.ownerDocument||this;for(l=c.target;l!=this;l=l.parentNode||this){o={},q=[],m[0]=l;for(j=0;j<e;j++)r=d[j],s=r.selector,o[s]===b&&(o[s]=r.quick?H(l,r.quick):m.is(s)),o[s]&&q.push(r);q.length&&i.push({elem:l,matches:q})}}d.length>e&&i.push({elem:this,matches:d.slice(e)});for(j=0;j<i.length&&!c.isPropagationStopped();j++){p=i[j],c.currentTarget=p.elem;for(k=0;k<p.matches.length&&!c.isImmediatePropagationStopped();k++){r=p.matches[k];if(h||!c.namespace&&!r.namespace||c.namespace_re&&c.namespace_re.test(r.namespace))c.data=r.data,c.handleObj=r,n=((f.event.special[r.origType]||{}).handle||r.handler).apply(p.elem,g),n!==b&&(c.result=n,n===!1&&(c.preventDefault(),c.stopPropagation()))}}return c.result},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){a.which==null&&(a.which=b.charCode!=null?b.charCode:b.keyCode);return a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,d){var e,f,g,h=d.button,i=d.fromElement;a.pageX==null&&d.clientX!=null&&(e=a.target.ownerDocument||c,f=e.documentElement,g=e.body,a.pageX=d.clientX+(f&&f.scrollLeft||g&&g.scrollLeft||0)-(f&&f.clientLeft||g&&g.clientLeft||0),a.pageY=d.clientY+(f&&f.scrollTop||g&&g.scrollTop||0)-(f&&f.clientTop||g&&g.clientTop||0)),!a.relatedTarget&&i&&(a.relatedTarget=i===a.target?d.toElement:i),!a.which&&h!==b&&(a.which=h&1?1:h&2?3:h&4?2:0);return a}},fix:function(a){if(a[f.expando])return a;var d,e,g=a,h=f.event.fixHooks[a.type]||{},i=h.props?this.props.concat(h.props):this.props;a=f.Event(g);for(d=i.length;d;)e=i[--d],a[e]=g[e];a.target||(a.target=g.srcElement||c),a.target.nodeType===3&&(a.target=a.target.parentNode),a.metaKey===b&&(a.metaKey=a.ctrlKey);return h.filter?h.filter(a,g):a},special:{ready:{setup:f.bindReady},load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(a,b,c){f.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}},simulate:function(a,b,c,d){var e=f.extend(new f.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?f.event.trigger(e,null,b):f.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},f.event.handle=f.event.dispatch,f.removeEvent=c.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){a.detachEvent&&a.detachEvent("on"+b,c)},f.Event=function(a,b){if(!(this instanceof f.Event))return new f.Event(a,b);a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?K:J):this.type=a,b&&f.extend(this,b),this.timeStamp=a&&a.timeStamp||f.now(),this[f.expando]=!0},f.Event.prototype={preventDefault:function(){this.isDefaultPrevented=K;var a=this.originalEvent;!a||(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){this.isPropagationStopped=K;var a=this.originalEvent;!a||(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=K,this.stopPropagation()},isDefaultPrevented:J,isPropagationStopped:J,isImmediatePropagationStopped:J},f.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){f.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c=this,d=a.relatedTarget,e=a.handleObj,g=e.selector,h;if(!d||d!==c&&!f.contains(c,d))a.type=e.origType,h=e.handler.apply(this,arguments),a.type=b;return h}}}),f.support.submitBubbles||(f.event.special.submit={setup:function(){if(f.nodeName(this,"form"))return!1;f.event.add(this,"click._submit keypress._submit",function(a){var c=a.target,d=f.nodeName(c,"input")||f.nodeName(c,"button")?c.form:b;d&&!d._submit_attached&&(f.event.add(d,"submit._submit",function(a){this.parentNode&&!a.isTrigger&&f.event.simulate("submit",this.parentNode,a,!0)}),d._submit_attached=!0)})},teardown:function(){if(f.nodeName(this,"form"))return!1;f.event.remove(this,"._submit")}}),f.support.changeBubbles||(f.event.special.change={setup:function(){if(z.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio")f.event.add(this,"propertychange._change",function(a){a.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),f.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1,f.event.simulate("change",this,a,!0))});return!1}f.event.add(this,"beforeactivate._change",function(a){var b=a.target;z.test(b.nodeName)&&!b._change_attached&&(f.event.add(b,"change._change",function(a){this.parentNode&&!a.isSimulated&&!a.isTrigger&&f.event.simulate("change",this.parentNode,a,!0)}),b._change_attached=!0)})},handle:function(a){var b=a.target;if(this!==b||a.isSimulated||a.isTrigger||b.type!=="radio"&&b.type!=="checkbox")return a.handleObj.handler.apply(this,arguments)},teardown:function(){f.event.remove(this,"._change");return z.test(this.nodeName)}}),f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){var d=0,e=function(a){f.event.simulate(b,a.target,f.event.fix(a),!0)};f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.fn.extend({on:function(a,c,d,e,g){var h,i;if(typeof a=="object"){typeof c!="string"&&(d=c,c=b);for(i in a)this.on(i,c,d,a[i],g);return this}d==null&&e==null?(e=c,d=c=b):e==null&&(typeof c=="string"?(e=d,d=b):(e=d,d=c,c=b));if(e===!1)e=J;else if(!e)return this;g===1&&(h=e,e=function(a){f().off(a);return h.apply(this,arguments)},e.guid=h.guid||(h.guid=f.guid++));return this.each(function(){f.event.add(this,a,e,d,c)})},one:function(a,b,c,d){return this.on.call(this,a,b,c,d,1)},off:function(a,c,d){if(a&&a.preventDefault&&a.handleObj){var e=a.handleObj;f(a.delegateTarget).off(e.namespace?e.type+"."+e.namespace:e.type,e.selector,e.handler);return this}if(typeof a=="object"){for(var g in a)this.off(g,c,a[g]);return this}if(c===!1||typeof c=="function")d=c,c=b;d===!1&&(d=J);return this.each(function(){f.event.remove(this,a,d,c)})},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},live:function(a,b,c){f(this.context).on(a,this.selector,b,c);return this},die:function(a,b){f(this.context).off(a,this.selector||"**",b);return this},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return arguments.length==1?this.off(a,"**"):this.off(b,a,c)},trigger:function(a,b){return this.each(function(){f.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return f.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||f.guid++,d=0,e=function(c){var e=(f._data(this,"lastToggle"+a.guid)||0)%d;f._data(this,"lastToggle"+a.guid,e+1),c.preventDefault();return b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),f.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){f.fn[b]=function(a,c){c==null&&(c=a,a=null);return arguments.length>0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}if(j.nodeType===1){g||(j[d]=c,j.sizset=h);if(typeof b!="string"){if(j===b){k=!0;break}}else if(m.filter(b,[j]).length>0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}j.nodeType===1&&!g&&(j[d]=c,j.sizset=h);if(j.nodeName.toLowerCase()===b){k=j;break}j=j[a]}e[h]=k}}}var a=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b<a.length;b++)a[b]===a[b-1]&&a.splice(b--,1)}return a},m.matches=function(a,b){return m(a,null,null,b)},m.matchesSelector=function(a,b){return m(b,null,null,[a]).length>0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e<f;e++){h=o.order[e];if(g=o.leftMatch[h].exec(a)){i=g[1],g.splice(1,1);if(i.substr(i.length-1)!=="\\"){g[1]=(g[1]||"").replace(j,""),d=o.find[h](g,b,c);if(d!=null){a=a.replace(o.match[h],"");break}}}}d||(d=typeof b.getElementsByTagName!="undefined"?b.getElementsByTagName("*"):[]);return{set:d,expr:a}},m.filter=function(a,c,d,e){var f,g,h,i,j,k,l,n,p,q=a,r=[],s=c,t=c&&c[0]&&m.isXML(c[0]);while(a&&c.length){for(h in o.filter)if((f=o.leftMatch[h].exec(a))!=null&&f[2]){k=o.filter[h],l=f[1],g=!1,f.splice(1,1);if(l.substr(l.length-1)==="\\")continue;s===r&&(r=[]);if(o.preFilter[h]){f=o.preFilter[h](f,s,d,r,e,t);if(!f)g=i=!0;else if(f===!0)continue}if(f)for(n=0;(j=s[n])!=null;n++)j&&(i=k(j,f,n,s),p=e^i,d&&i!=null?p?g=!0:s[n]=!1:p&&(r.push(j),g=!0));if(i!==b){d||(s=r),a=a.replace(o.match[h],"");if(!g)return[];break}}if(a===q)if(g==null)m.error(a);else break;q=a}return s},m.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)};var n=m.getText=function(a){var b,c,d=a.nodeType,e="";if(d){if(d===1||d===9){if(typeof a.textContent=="string")return a.textContent;if(typeof a.innerText=="string")return a.innerText.replace(k,"");for(a=a.firstChild;a;a=a.nextSibling)e+=n(a)}else if(d===3||d===4)return a.nodeValue}else for(b=0;c=a[b];b++)c.nodeType!==8&&(e+=n(c));return e},o=m.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(a){return a.getAttribute("href")},type:function(a){return a.getAttribute("type")}},relative:{"+":function(a,b){var c=typeof b=="string",d=c&&!l.test(b),e=c&&!d;d&&(b=b.toLowerCase());for(var f=0,g=a.length,h;f<g;f++)if(h=a[f]){while((h=h.previousSibling)&&h.nodeType!==1);a[f]=e||h&&h.nodeName.toLowerCase()===b?h||!1:h===b}e&&m.filter(b,a,!0)},">":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e<f;e++){c=a[e];if(c){var g=c.parentNode;a[e]=g.nodeName.toLowerCase()===b?g:!1}}}else{for(;e<f;e++)c=a[e],c&&(a[e]=d?c.parentNode:c.parentNode===b);d&&m.filter(b,a,!0)}},"":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("parentNode",b,f,a,d,c)},"~":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("previousSibling",b,f,a,d,c)}},find:{ID:function(a,b,c){if(typeof b.getElementById!="undefined"&&!c){var d=b.getElementById(a[1]);return d&&d.parentNode?[d]:[]}},NAME:function(a,b){if(typeof b.getElementsByName!="undefined"){var c=[],d=b.getElementsByName(a[1]);for(var e=0,f=d.length;e<f;e++)d[e].getAttribute("name")===a[1]&&c.push(d[e]);return c.length===0?null:c}},TAG:function(a,b){if(typeof b.getElementsByTagName!="undefined")return b.getElementsByTagName(a[1])}},preFilter:{CLASS:function(a,b,c,d,e,f){a=" "+a[1].replace(j,"")+" ";if(f)return a;for(var g=0,h;(h=b[g])!=null;g++)h&&(e^(h.className&&(" "+h.className+" ").replace(/[\t\n\r]/g," ").indexOf(a)>=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return b<c[3]-0},gt:function(a,b,c){return b>c[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h<i;h++)if(g[h]===a)return!1;return!0}m.error(e)},CHILD:function(a,b){var c,e,f,g,h,i,j,k=b[1],l=a;switch(k){case"only":case"first":while(l=l.previousSibling)if(l.nodeType===1)return!1;if(k==="first")return!0;l=a;case"last":while(l=l.nextSibling)if(l.nodeType===1)return!1;return!0;case"nth":c=b[2],e=b[3];if(c===1&&e===0)return!0;f=b[0],g=a.parentNode;if(g&&(g[d]!==f||!a.nodeIndex)){i=0;for(l=g.firstChild;l;l=l.nextSibling)l.nodeType===1&&(l.nodeIndex=++i);g[d]=f}j=a.nodeIndex-e;return c===0?j===0:j%c===0&&j/c>=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c<e;c++)d.push(a[c]);else for(;a[c];c++)d.push(a[c]);return d}}var u,v;c.documentElement.compareDocumentPosition?u=function(a,b){if(a===b){h=!0;return 0}if(!a.compareDocumentPosition||!b.compareDocumentPosition)return a.compareDocumentPosition?-1:1;return a.compareDocumentPosition(b)&4?-1:1}:(u=function(a,b){if(a===b){h=!0;return 0}if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],f=[],g=a.parentNode,i=b.parentNode,j=g;if(g===i)return v(a,b);if(!g)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)f.unshift(j),j=j.parentNode;c=e.length,d=f.length;for(var k=0;k<c&&k<d;k++)if(e[k]!==f[k])return v(e[k],f[k]);return k===c?v(a,f[k],-1):v(e[k],b,1)},v=function(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}),function(){var a=c.createElement("div"),d="script"+(new Date).getTime(),e=c.documentElement;a.innerHTML="<a name='"+d+"'/>",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="<p class='TEST'></p>";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="<div class='test e'></div><div class='test'></div>";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h<i;h++)m(a,g[h],e,c);return m.filter(f,e)};m.attr=f.attr,m.selectors.attrMap={},f.find=m,f.expr=m.selectors,f.expr[":"]=f.expr.filters,f.unique=m.uniqueSort,f.text=m.getText,f.isXMLDoc=m.isXML,f.contains=m.contains}();var L=/Until$/,M=/^(?:parents|prevUntil|prevAll)/,N=/,/,O=/^.[^:#\[\.,]*$/,P=Array.prototype.slice,Q=f.expr.match.POS,R={children:!0,contents:!0,next:!0,prev:!0};f.fn.extend({find:function(a){var b=this,c,d;if(typeof a!="string")return f(a).filter(function(){for(c=0,d=b.length;c<d;c++)if(f.contains(b[c],this))return!0});var e=this.pushStack("","find",a),g,h,i;for(c=0,d=this.length;c<d;c++){g=e.length,f.find(a,this[c],e);if(c>0)for(h=g;h<e.length;h++)for(i=0;i<g;i++)if(e[i]===e[h]){e.splice(h--,1);break}}return e},has:function(a){var b=f(a);return this.filter(function(){for(var a=0,c=b.length;a<c;a++)if(f.contains(this,b[a]))return!0})},not:function(a){return this.pushStack(T(this,a,!1),"not",a)},filter:function(a){return this.pushStack(T(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?Q.test(a)?f(a,this.context).index(this[0])>=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d<a.length;d++)f(g).is(a[d])&&c.push({selector:a[d],elem:g,level:h});g=g.parentNode,h++}return c}var i=Q.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d<e;d++){g=this[d];while(g){if(i?i.index(g)>-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/<tbody/i,_=/<|&#?\w+;/,ba=/<(?:script|style)/i,bb=/<(?:script|object|embed|option|style)/i,bc=new RegExp("<(?:"+V+")","i"),bd=/checked\s*(?:[^=]|=\s*.checked.)/i,be=/\/(java|ecma)script/i,bf=/^\s*<!(?:\[CDATA\[|\-\-)/,bg={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div<div>","</div>"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function()
4
+ {for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1></$2>");try{for(var c=0,d=this.length;c<d;c++)this[c].nodeType===1&&(f.cleanData(this[c].getElementsByTagName("*")),this[c].innerHTML=a)}catch(e){this.empty().append(a)}}else f.isFunction(a)?this.each(function(b){var c=f(this);c.html(a.call(this,b,c.html()))}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(f.isFunction(a))return this.each(function(b){var c=f(this),d=c.html();c.replaceWith(a.call(this,b,d))});typeof a!="string"&&(a=f(a).detach());return this.each(function(){var b=this.nextSibling,c=this.parentNode;f(this).remove(),b?f(b).before(a):f(c).append(a)})}return this.length?this.pushStack(f(f.isFunction(a)?a():a),"replaceWith",a):this},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){var e,g,h,i,j=a[0],k=[];if(!f.support.checkClone&&arguments.length===3&&typeof j=="string"&&bd.test(j))return this.each(function(){f(this).domManip(a,c,d,!0)});if(f.isFunction(j))return this.each(function(e){var g=f(this);a[0]=j.call(this,e,c?g.html():b),g.domManip(a,c,d)});if(this[0]){i=j&&j.parentNode,f.support.parentNode&&i&&i.nodeType===11&&i.childNodes.length===this.length?e={fragment:i}:e=f.buildFragment(a,this,k),h=e.fragment,h.childNodes.length===1?g=h=h.firstChild:g=h.firstChild;if(g){c=c&&f.nodeName(g,"tr");for(var l=0,m=this.length,n=m-1;l<m;l++)d.call(c?bi(this[l],g):this[l],e.cacheable||m>1&&l<n?f.clone(h,!0,!0):h)}k.length&&f.each(k,bp)}return this}}),f.buildFragment=function(a,b,d){var e,g,h,i,j=a[0];b&&b[0]&&(i=b[0].ownerDocument||b[0]),i.createDocumentFragment||(i=c),a.length===1&&typeof j=="string"&&j.length<512&&i===c&&j.charAt(0)==="<"&&!bb.test(j)&&(f.support.checkClone||!bd.test(j))&&(f.support.html5Clone||!bc.test(j))&&(g=!0,h=f.fragments[j],h&&h!==1&&(e=h)),e||(e=i.createDocumentFragment(),f.clean(a,i,e,d)),g&&(f.fragments[j]=h?e:1);return{fragment:e,cacheable:g}},f.fragments={},f.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){f.fn[a]=function(c){var d=[],e=f(c),g=this.length===1&&this[0].parentNode;if(g&&g.nodeType===11&&g.childNodes.length===1&&e.length===1){e[b](this[0]);return this}for(var h=0,i=e.length;h<i;h++){var j=(h>0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||!bc.test("<"+a.nodeName)?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1></$2>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");b===c?bh.appendChild(o):U(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]==="<table>"&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i<r;i++)bn(k[i]);else bn(k);k.nodeType?h.push(k):h=f.merge(h,k)}if(d){g=function(a){return!a.type||be.test(a.type)};for(j=0;h[j];j++)if(e&&f.nodeName(h[j],"script")&&(!h[j].type||h[j].type.toLowerCase()==="text/javascript"))e.push(h[j].parentNode?h[j].parentNode.removeChild(h[j]):h[j]);else{if(h[j].nodeType===1){var s=f.grep(h[j].getElementsByTagName("script"),g);h.splice.apply(h,[j+1,0].concat(s))}d.appendChild(h[j])}}return h},cleanData:function(a){var b,c,d=f.cache,e=f.event.special,g=f.support.deleteExpando;for(var h=0,i;(i=a[h])!=null;h++){if(i.nodeName&&f.noData[i.nodeName.toLowerCase()])continue;c=i[f.expando];if(c){b=d[c];if(b&&b.events){for(var j in b.events)e[j]?f.event.remove(i,j):f.removeEvent(i,j,b.handle);b.handle&&(b.handle.elem=null)}g?delete i[f.expando]:i.removeAttribute&&i.removeAttribute(f.expando),delete d[c]}}}});var bq=/alpha\([^)]*\)/i,br=/opacity=([^)]*)/,bs=/([A-Z]|^ms)/g,bt=/^-?\d+(?:px)?$/i,bu=/^-?\d/,bv=/^([\-+])=([\-+.\de]+)/,bw={position:"absolute",visibility:"hidden",display:"block"},bx=["Left","Right"],by=["Top","Bottom"],bz,bA,bB;f.fn.css=function(a,c){if(arguments.length===2&&c===b)return this;return f.access(this,a,c,!0,function(a,c,d){return d!==b?f.style(a,c,d):f.css(a,c)})},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bz(a,"opacity","opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d,h==="string"&&(g=bv.exec(d))&&(d=+(g[1]+1)*+g[2]+parseFloat(f.css(a,c)),h="number");if(d==null||h==="number"&&isNaN(d))return;h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(bz)return bz(a,c)},swap:function(a,b,c){var d={};for(var e in b)d[e]=a.style[e],a.style[e]=b[e];c.call(a);for(e in b)a.style[e]=d[e]}}),f.curCSS=f.css,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){var e;if(c){if(a.offsetWidth!==0)return bC(a,b,d);f.swap(a,bw,function(){e=bC(a,b,d)});return e}},set:function(a,b){if(!bt.test(b))return b;b=parseFloat(b);if(b>=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return br.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bq,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bq.test(g)?g.replace(bq,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,b){var c,d,e;b=b.replace(bs,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b)));return c}),c.documentElement.currentStyle&&(bB=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bt.test(f)&&bu.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bz=bA||bB,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bD=/%20/g,bE=/\[\]$/,bF=/\r?\n/g,bG=/#.*$/,bH=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bI=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bJ=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bK=/^(?:GET|HEAD)$/,bL=/^\/\//,bM=/\?/,bN=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bO=/^(?:select|textarea)/i,bP=/\s+/,bQ=/([?&])_=[^&]*/,bR=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bS=f.fn.load,bT={},bU={},bV,bW,bX=["*/"]+["*"];try{bV=e.href}catch(bY){bV=c.createElement("a"),bV.href="",bV=bV.href}bW=bR.exec(bV.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bS)return bS.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("<div>").append(c.replace(bN,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bO.test(this.nodeName)||bI.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bF,"\r\n")}}):{name:b.name,value:c.replace(bF,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b_(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b_(a,b);return a},ajaxSettings:{url:bV,isLocal:bJ.test(bW[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bX},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bZ(bT),ajaxTransport:bZ(bU),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?cb(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cc(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bH.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bG,"").replace(bL,bW[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bP),d.crossDomain==null&&(r=bR.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bW[1]&&r[2]==bW[2]&&(r[3]||(r[1]==="http:"?80:443))==(bW[3]||(bW[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),b$(bT,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bK.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bM.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bQ,"$1_="+x);d.url=y+(y===d.url?(bM.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bX+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=b$(bU,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)ca(g,a[g],c,e);return d.join("&").replace(bD,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cd=f.now(),ce=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cd++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ce.test(b.url)||e&&ce.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ce,l),b.url===j&&(e&&(k=k.replace(ce,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cf=a.ActiveXObject?function(){for(var a in ch)ch[a](0,1)}:!1,cg=0,ch;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ci()||cj()}:ci,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cf&&delete ch[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cg,cf&&(ch||(ch={},f(a).unload(cf)),ch[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var ck={},cl,cm,cn=/^(?:toggle|show|hide)$/,co=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cp,cq=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cr;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cu("show",3),a,b,c);for(var g=0,h=this.length;g<h;g++)d=this[g],d.style&&(e=d.style.display,!f._data(d,"olddisplay")&&e==="none"&&(e=d.style.display=""),e===""&&f.css(d,"display")==="none"&&f._data(d,"olddisplay",cv(d.nodeName)));for(g=0;g<h;g++){d=this[g];if(d.style){e=d.style.display;if(e===""||e==="none")d.style.display=f._data(d,"olddisplay")||""}}return this},hide:function(a,b,c){if(a||a===0)return this.animate(cu("hide",3),a,b,c);var d,e,g=0,h=this.length;for(;g<h;g++)d=this[g],d.style&&(e=f.css(d,"display"),e!=="none"&&!f._data(d,"olddisplay")&&f._data(d,"olddisplay",e));for(g=0;g<h;g++)this[g].style&&(this[g].style.display="none");return this},_toggle:f.fn.toggle,toggle:function(a,b,c){var d=typeof a=="boolean";f.isFunction(a)&&f.isFunction(b)?this._toggle.apply(this,arguments):a==null||d?this.each(function(){var b=d?a:f(this).is(":hidden");f(this)[b?"show":"hide"]()}):this.animate(cu("toggle",3),a,b,c);return this},fadeTo:function(a,b,c,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){function g(){e.queue===!1&&f._mark(this);var b=f.extend({},e),c=this.nodeType===1,d=c&&f(this).is(":hidden"),g,h,i,j,k,l,m,n,o;b.animatedProperties={};for(i in a){g=f.camelCase(i),i!==g&&(a[g]=a[i],delete a[i]),h=a[g],f.isArray(h)?(b.animatedProperties[g]=h[1],h=a[g]=h[0]):b.animatedProperties[g]=b.specialEasing&&b.specialEasing[g]||b.easing||"swing";if(h==="hide"&&d||h==="show"&&!d)return b.complete.call(this);c&&(g==="height"||g==="width")&&(b.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY],f.css(this,"display")==="inline"&&f.css(this,"float")==="none"&&(!f.support.inlineBlockNeedsLayout||cv(this.nodeName)==="inline"?this.style.display="inline-block":this.style.zoom=1))}b.overflow!=null&&(this.style.overflow="hidden");for(i in a)j=new f.fx(this,b,i),h=a[i],cn.test(h)?(o=f._data(this,"toggle"+i)||(h==="toggle"?d?"show":"hide":0),o?(f._data(this,"toggle"+i,o==="show"?"hide":"show"),j[o]()):j[h]()):(k=co.exec(h),l=j.cur(),k?(m=parseFloat(k[2]),n=k[3]||(f.cssNumber[i]?"":"px"),n!=="px"&&(f.style(this,i,(m||1)+n),l=(m||1)/j.cur()*l,f.style(this,i,l+n)),k[1]&&(m=(k[1]==="-="?-1:1)*m+l),j.custom(l,m,n)):j.custom(l,h,""));return!0}var e=f.speed(b,c,d);if(f.isEmptyObject(a))return this.each(e.complete,[!1]);a=f.extend({},a);return e.queue===!1?this.each(g):this.queue(e.queue,g)},stop:function(a,c,d){typeof a!="string"&&(d=c,c=a,a=b),c&&a!==!1&&this.queue(a||"fx",[]);return this.each(function(){function h(a,b,c){var e=b[c];f.removeData(a,c,!0),e.stop(d)}var b,c=!1,e=f.timers,g=f._data(this);d||f._unmark(!0,this);if(a==null)for(b in g)g[b]&&g[b].stop&&b.indexOf(".run")===b.length-4&&h(this,g,b);else g[b=a+".run"]&&g[b].stop&&h(this,g,b);for(b=e.length;b--;)e[b].elem===this&&(a==null||e[b].queue===a)&&(d?e[b](!0):e[b].saveState(),c=!0,e.splice(b,1));(!d||!c)&&f.dequeue(this,a)})}}),f.each({slideDown:cu("show",1),slideUp:cu("hide",1),slideToggle:cu("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){f.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),f.extend({speed:function(a,b,c){var d=a&&typeof a=="object"?f.extend({},a):{complete:c||!c&&b||f.isFunction(a)&&a,duration:a,easing:c&&b||b&&!f.isFunction(b)&&b};d.duration=f.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in f.fx.speeds?f.fx.speeds[d.duration]:f.fx.speeds._default;if(d.queue==null||d.queue===!0)d.queue="fx";d.old=d.complete,d.complete=function(a){f.isFunction(d.old)&&d.old.call(this),d.queue?f.dequeue(this,d.queue):a!==!1&&f._unmark(this)};return d},easing:{linear:function(a,b,c,d){return c+d*a},swing:function(a,b,c,d){return(-Math.cos(a*Math.PI)/2+.5)*d+c}},timers:[],fx:function(a,b,c){this.options=b,this.elem=a,this.prop=c,b.orig=b.orig||{}}}),f.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(f.fx.step[this.prop]||f.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a,b=f.css(this.elem,this.prop);return isNaN(a=parseFloat(b))?!b||b==="auto"?0:b:a},custom:function(a,c,d){function h(a){return e.step(a)}var e=this,g=f.fx;this.startTime=cr||cs(),this.end=c,this.now=this.start=a,this.pos=this.state=0,this.unit=d||this.unit||(f.cssNumber[this.prop]?"":"px"),h.queue=this.options.queue,h.elem=this.elem,h.saveState=function(){e.options.hide&&f._data(e.elem,"fxshow"+e.prop)===b&&f._data(e.elem,"fxshow"+e.prop,e.start)},h()&&f.timers.push(h)&&!cp&&(cp=setInterval(g.tick,g.interval))},show:function(){var a=f._data(this.elem,"fxshow"+this.prop);this.options.orig[this.prop]=a||f.style(this.elem,this.prop),this.options.show=!0,a!==b?this.custom(this.cur(),a):this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur()),f(this.elem).show()},hide:function(){this.options.orig[this.prop]=f._data(this.elem,"fxshow"+this.prop)||f.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(a){var b,c,d,e=cr||cs(),g=!0,h=this.elem,i=this.options;if(a||e>=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c<b.length;c++)a=b[c],!a()&&b[c]===a&&b.splice(c--,1);b.length||f.fx.stop()},interval:13,stop:function(){clearInterval(cp),cp=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){f.style(a.elem,"opacity",a.now)},_default:function(a){a.elem.style&&a.elem.style[a.prop]!=null?a.elem.style[a.prop]=a.now+a.unit:a.elem[a.prop]=a.now}}}),f.each(["width","height"],function(a,b){f.fx.step[b]=function(a){f.style(a.elem,b,Math.max(0,a.now)+a.unit)}}),f.expr&&f.expr.filters&&(f.expr.filters.animated=function(a){return f.grep(f.timers,function(b){return a===b.elem}).length});var cw=/^t(?:able|d|h)$/i,cx=/^(?:body|html)$/i;"getBoundingClientRect"in c.documentElement?f.fn.offset=function(a){var b=this[0],c;if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);try{c=b.getBoundingClientRect()}catch(d){}var e=b.ownerDocument,g=e.documentElement;if(!c||!f.contains(g,b))return c?{top:c.top,left:c.left}:{top:0,left:0};var h=e.body,i=cy(e),j=g.clientTop||h.clientTop||0,k=g.clientLeft||h.clientLeft||0,l=i.pageYOffset||f.support.boxModel&&g.scrollTop||h.scrollTop,m=i.pageXOffset||f.support.boxModel&&g.scrollLeft||h.scrollLeft,n=c.top+l-j,o=c.left+m-k;return{top:n,left:o}}:f.fn.offset=function(a){var b=this[0];if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);var c,d=b.offsetParent,e=b,g=b.ownerDocument,h=g.documentElement,i=g.body,j=g.defaultView,k=j?j.getComputedStyle(b,null):b.currentStyle,l=b.offsetTop,m=b.offsetLeft;while((b=b.parentNode)&&b!==i&&b!==h){if(f.support.fixedPosition&&k.position==="fixed")break;c=j?j.getComputedStyle(b,null):b.currentStyle,l-=b.scrollTop,m-=b.scrollLeft,b===d&&(l+=b.offsetTop,m+=b.offsetLeft,f.support.doesNotAddBorder&&(!f.support.doesAddBorderForTableAndCells||!cw.test(b.nodeName))&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),e=d,d=b.offsetParent),f.support.subtractsBorderForOverflowNotVisible&&c.overflow!=="visible"&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),k=c}if(k.position==="relative"||k.position==="static")l+=i.offsetTop,m+=i.offsetLeft;f.support.fixedPosition&&k.position==="fixed"&&(l+=Math.max(h.scrollTop,i.scrollTop),m+=Math.max(h.scrollLeft,i.scrollLeft));return{top:l,left:m}},f.offset={bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.support.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cy(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cy(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this[d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window);
js/prototype.js ADDED
@@ -0,0 +1,6082 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Prototype JavaScript framework, version 1.7
2
+ * (c) 2005-2010 Sam Stephenson
3
+ *
4
+ * Prototype is freely distributable under the terms of an MIT-style license.
5
+ * For details, see the Prototype web site: http://www.prototypejs.org/
6
+ *
7
+ *--------------------------------------------------------------------------*/
8
+
9
+ var Prototype = {
10
+
11
+ Version: '1.7',
12
+
13
+ Browser: (function(){
14
+ var ua = navigator.userAgent;
15
+ var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]';
16
+ return {
17
+ IE: !!window.attachEvent && !isOpera,
18
+ Opera: isOpera,
19
+ WebKit: ua.indexOf('AppleWebKit/') > -1,
20
+ Gecko: ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') === -1,
21
+ MobileSafari: /Apple.*Mobile/.test(ua)
22
+ }
23
+ })(),
24
+
25
+ BrowserFeatures: {
26
+ XPath: !!document.evaluate,
27
+
28
+ SelectorsAPI: !!document.querySelector,
29
+
30
+ ElementExtensions: (function() {
31
+ var constructor = window.Element || window.HTMLElement;
32
+ return !!(constructor && constructor.prototype);
33
+ })(),
34
+ SpecificElementExtensions: (function() {
35
+ if (typeof window.HTMLDivElement !== 'undefined')
36
+ return true;
37
+
38
+ var div = document.createElement('div'),
39
+ form = document.createElement('form'),
40
+ isSupported = false;
41
+
42
+ if (div['__proto__'] && (div['__proto__'] !== form['__proto__'])) {
43
+ isSupported = true;
44
+ }
45
+
46
+ div = form = null;
47
+
48
+ return isSupported;
49
+ })()
50
+ },
51
+
52
+ ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',
53
+ JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,
54
+
55
+ emptyFunction: function() { },
56
+
57
+ K: function(x) { return x }
58
+ };
59
+
60
+ if (Prototype.Browser.MobileSafari)
61
+ Prototype.BrowserFeatures.SpecificElementExtensions = false;
62
+
63
+
64
+ var Abstract = { };
65
+
66
+
67
+ var Try = {
68
+ these: function() {
69
+ var returnValue;
70
+
71
+ for (var i = 0, length = arguments.length; i < length; i++) {
72
+ var lambda = arguments[i];
73
+ try {
74
+ returnValue = lambda();
75
+ break;
76
+ } catch (e) { }
77
+ }
78
+
79
+ return returnValue;
80
+ }
81
+ };
82
+
83
+ /* Based on Alex Arnell's inheritance implementation. */
84
+
85
+ var Class = (function() {
86
+
87
+ var IS_DONTENUM_BUGGY = (function(){
88
+ for (var p in { toString: 1 }) {
89
+ if (p === 'toString') return false;
90
+ }
91
+ return true;
92
+ })();
93
+
94
+ function subclass() {};
95
+ function create() {
96
+ var parent = null, properties = $A(arguments);
97
+ if (Object.isFunction(properties[0]))
98
+ parent = properties.shift();
99
+
100
+ function klass() {
101
+ this.initialize.apply(this, arguments);
102
+ }
103
+
104
+ Object.extend(klass, Class.Methods);
105
+ klass.superclass = parent;
106
+ klass.subclasses = [];
107
+
108
+ if (parent) {
109
+ subclass.prototype = parent.prototype;
110
+ klass.prototype = new subclass;
111
+ parent.subclasses.push(klass);
112
+ }
113
+
114
+ for (var i = 0, length = properties.length; i < length; i++)
115
+ klass.addMethods(properties[i]);
116
+
117
+ if (!klass.prototype.initialize)
118
+ klass.prototype.initialize = Prototype.emptyFunction;
119
+
120
+ klass.prototype.constructor = klass;
121
+ return klass;
122
+ }
123
+
124
+ function addMethods(source) {
125
+ var ancestor = this.superclass && this.superclass.prototype,
126
+ properties = Object.keys(source);
127
+
128
+ if (IS_DONTENUM_BUGGY) {
129
+ if (source.toString != Object.prototype.toString)
130
+ properties.push("toString");
131
+ if (source.valueOf != Object.prototype.valueOf)
132
+ properties.push("valueOf");
133
+ }
134
+
135
+ for (var i = 0, length = properties.length; i < length; i++) {
136
+ var property = properties[i], value = source[property];
137
+ if (ancestor && Object.isFunction(value) &&
138
+ value.argumentNames()[0] == "$super") {
139
+ var method = value;
140
+ value = (function(m) {
141
+ return function() { return ancestor[m].apply(this, arguments); };
142
+ })(property).wrap(method);
143
+
144
+ value.valueOf = method.valueOf.bind(method);
145
+ value.toString = method.toString.bind(method);
146
+ }
147
+ this.prototype[property] = value;
148
+ }
149
+
150
+ return this;
151
+ }
152
+
153
+ return {
154
+ create: create,
155
+ Methods: {
156
+ addMethods: addMethods
157
+ }
158
+ };
159
+ })();
160
+ (function() {
161
+
162
+ var _toString = Object.prototype.toString,
163
+ NULL_TYPE = 'Null',
164
+ UNDEFINED_TYPE = 'Undefined',
165
+ BOOLEAN_TYPE = 'Boolean',
166
+ NUMBER_TYPE = 'Number',
167
+ STRING_TYPE = 'String',
168
+ OBJECT_TYPE = 'Object',
169
+ FUNCTION_CLASS = '[object Function]',
170
+ BOOLEAN_CLASS = '[object Boolean]',
171
+ NUMBER_CLASS = '[object Number]',
172
+ STRING_CLASS = '[object String]',
173
+ ARRAY_CLASS = '[object Array]',
174
+ DATE_CLASS = '[object Date]',
175
+ NATIVE_JSON_STRINGIFY_SUPPORT = window.JSON &&
176
+ typeof JSON.stringify === 'function' &&
177
+ JSON.stringify(0) === '0' &&
178
+ typeof JSON.stringify(Prototype.K) === 'undefined';
179
+
180
+ function Type(o) {
181
+ switch(o) {
182
+ case null: return NULL_TYPE;
183
+ case (void 0): return UNDEFINED_TYPE;
184
+ }
185
+ var type = typeof o;
186
+ switch(type) {
187
+ case 'boolean': return BOOLEAN_TYPE;
188
+ case 'number': return NUMBER_TYPE;
189
+ case 'string': return STRING_TYPE;
190
+ }
191
+ return OBJECT_TYPE;
192
+ }
193
+
194
+ function extend(destination, source) {
195
+ for (var property in source)
196
+ destination[property] = source[property];
197
+ return destination;
198
+ }
199
+
200
+ function inspect(object) {
201
+ try {
202
+ if (isUndefined(object)) return 'undefined';
203
+ if (object === null) return 'null';
204
+ return object.inspect ? object.inspect() : String(object);
205
+ } catch (e) {
206
+ if (e instanceof RangeError) return '...';
207
+ throw e;
208
+ }
209
+ }
210
+
211
+ function toJSON(value) {
212
+ return Str('', { '': value }, []);
213
+ }
214
+
215
+ function Str(key, holder, stack) {
216
+ var value = holder[key],
217
+ type = typeof value;
218
+
219
+ if (Type(value) === OBJECT_TYPE && typeof value.toJSON === 'function') {
220
+ value = value.toJSON(key);
221
+ }
222
+
223
+ var _class = _toString.call(value);
224
+
225
+ switch (_class) {
226
+ case NUMBER_CLASS:
227
+ case BOOLEAN_CLASS:
228
+ case STRING_CLASS:
229
+ value = value.valueOf();
230
+ }
231
+
232
+ switch (value) {
233
+ case null: return 'null';
234
+ case true: return 'true';
235
+ case false: return 'false';
236
+ }
237
+
238
+ type = typeof value;
239
+ switch (type) {
240
+ case 'string':
241
+ return value.inspect(true);
242
+ case 'number':
243
+ return isFinite(value) ? String(value) : 'null';
244
+ case 'object':
245
+
246
+ for (var i = 0, length = stack.length; i < length; i++) {
247
+ if (stack[i] === value) { throw new TypeError(); }
248
+ }
249
+ stack.push(value);
250
+
251
+ var partial = [];
252
+ if (_class === ARRAY_CLASS) {
253
+ for (var i = 0, length = value.length; i < length; i++) {
254
+ var str = Str(i, value, stack);
255
+ partial.push(typeof str === 'undefined' ? 'null' : str);
256
+ }
257
+ partial = '[' + partial.join(',') + ']';
258
+ } else {
259
+ var keys = Object.keys(value);
260
+ for (var i = 0, length = keys.length; i < length; i++) {
261
+ var key = keys[i], str = Str(key, value, stack);
262
+ if (typeof str !== "undefined") {
263
+ partial.push(key.inspect(true)+ ':' + str);
264
+ }
265
+ }
266
+ partial = '{' + partial.join(',') + '}';
267
+ }
268
+ stack.pop();
269
+ return partial;
270
+ }
271
+ }
272
+
273
+ function stringify(object) {
274
+ return JSON.stringify(object);
275
+ }
276
+
277
+ function toQueryString(object) {
278
+ return $H(object).toQueryString();
279
+ }
280
+
281
+ function toHTML(object) {
282
+ return object && object.toHTML ? object.toHTML() : String.interpret(object);
283
+ }
284
+
285
+ function keys(object) {
286
+ if (Type(object) !== OBJECT_TYPE) { throw new TypeError(); }
287
+ var results = [];
288
+ for (var property in object) {
289
+ if (object.hasOwnProperty(property)) {
290
+ results.push(property);
291
+ }
292
+ }
293
+ return results;
294
+ }
295
+
296
+ function values(object) {
297
+ var results = [];
298
+ for (var property in object)
299
+ results.push(object[property]);
300
+ return results;
301
+ }
302
+
303
+ function clone(object) {
304
+ return extend({ }, object);
305
+ }
306
+
307
+ function isElement(object) {
308
+ return !!(object && object.nodeType == 1);
309
+ }
310
+
311
+ function isArray(object) {
312
+ return _toString.call(object) === ARRAY_CLASS;
313
+ }
314
+
315
+ var hasNativeIsArray = (typeof Array.isArray == 'function')
316
+ && Array.isArray([]) && !Array.isArray({});
317
+
318
+ if (hasNativeIsArray) {
319
+ isArray = Array.isArray;
320
+ }
321
+
322
+ function isHash(object) {
323
+ return object instanceof Hash;
324
+ }
325
+
326
+ function isFunction(object) {
327
+ return _toString.call(object) === FUNCTION_CLASS;
328
+ }
329
+
330
+ function isString(object) {
331
+ return _toString.call(object) === STRING_CLASS;
332
+ }
333
+
334
+ function isNumber(object) {
335
+ return _toString.call(object) === NUMBER_CLASS;
336
+ }
337
+
338
+ function isDate(object) {
339
+ return _toString.call(object) === DATE_CLASS;
340
+ }
341
+
342
+ function isUndefined(object) {
343
+ return typeof object === "undefined";
344
+ }
345
+
346
+ extend(Object, {
347
+ extend: extend,
348
+ inspect: inspect,
349
+ toJSON: NATIVE_JSON_STRINGIFY_SUPPORT ? stringify : toJSON,
350
+ toQueryString: toQueryString,
351
+ toHTML: toHTML,
352
+ keys: Object.keys || keys,
353
+ values: values,
354
+ clone: clone,
355
+ isElement: isElement,
356
+ isArray: isArray,
357
+ isHash: isHash,
358
+ isFunction: isFunction,
359
+ isString: isString,
360
+ isNumber: isNumber,
361
+ isDate: isDate,
362
+ isUndefined: isUndefined
363
+ });
364
+ })();
365
+ Object.extend(Function.prototype, (function() {
366
+ var slice = Array.prototype.slice;
367
+
368
+ function update(array, args) {
369
+ var arrayLength = array.length, length = args.length;
370
+ while (length--) array[arrayLength + length] = args[length];
371
+ return array;
372
+ }
373
+
374
+ function merge(array, args) {
375
+ array = slice.call(array, 0);
376
+ return update(array, args);
377
+ }
378
+
379
+ function argumentNames() {
380
+ var names = this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1]
381
+ .replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '')
382
+ .replace(/\s+/g, '').split(',');
383
+ return names.length == 1 && !names[0] ? [] : names;
384
+ }
385
+
386
+ function bind(context) {
387
+ if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;
388
+ var __method = this, args = slice.call(arguments, 1);
389
+ return function() {
390
+ var a = merge(args, arguments);
391
+ return __method.apply(context, a);
392
+ }
393
+ }
394
+
395
+ function bindAsEventListener(context) {
396
+ var __method = this, args = slice.call(arguments, 1);
397
+ return function(event) {
398
+ var a = update([event || window.event], args);
399
+ return __method.apply(context, a);
400
+ }
401
+ }
402
+
403
+ function curry() {
404
+ if (!arguments.length) return this;
405
+ var __method = this, args = slice.call(arguments, 0);
406
+ return function() {
407
+ var a = merge(args, arguments);
408
+ return __method.apply(this, a);
409
+ }
410
+ }
411
+
412
+ function delay(timeout) {
413
+ var __method = this, args = slice.call(arguments, 1);
414
+ timeout = timeout * 1000;
415
+ return window.setTimeout(function() {
416
+ return __method.apply(__method, args);
417
+ }, timeout);
418
+ }
419
+
420
+ function defer() {
421
+ var args = update([0.01], arguments);
422
+ return this.delay.apply(this, args);
423
+ }
424
+
425
+ function wrap(wrapper) {
426
+ var __method = this;
427
+ return function() {
428
+ var a = update([__method.bind(this)], arguments);
429
+ return wrapper.apply(this, a);
430
+ }
431
+ }
432
+
433
+ function methodize() {
434
+ if (this._methodized) return this._methodized;
435
+ var __method = this;
436
+ return this._methodized = function() {
437
+ var a = update([this], arguments);
438
+ return __method.apply(null, a);
439
+ };
440
+ }
441
+
442
+ return {
443
+ argumentNames: argumentNames,
444
+ bind: bind,
445
+ bindAsEventListener: bindAsEventListener,
446
+ curry: curry,
447
+ delay: delay,
448
+ defer: defer,
449
+ wrap: wrap,
450
+ methodize: methodize
451
+ }
452
+ })());
453
+
454
+
455
+
456
+ (function(proto) {
457
+
458
+
459
+ function toISOString() {
460
+ return this.getUTCFullYear() + '-' +
461
+ (this.getUTCMonth() + 1).toPaddedString(2) + '-' +
462
+ this.getUTCDate().toPaddedString(2) + 'T' +
463
+ this.getUTCHours().toPaddedString(2) + ':' +
464
+ this.getUTCMinutes().toPaddedString(2) + ':' +
465
+ this.getUTCSeconds().toPaddedString(2) + 'Z';
466
+ }
467
+
468
+
469
+ function toJSON() {
470
+ return this.toISOString();
471
+ }
472
+
473
+ if (!proto.toISOString) proto.toISOString = toISOString;
474
+ if (!proto.toJSON) proto.toJSON = toJSON;
475
+
476
+ })(Date.prototype);
477
+
478
+
479
+ RegExp.prototype.match = RegExp.prototype.test;
480
+
481
+ RegExp.escape = function(str) {
482
+ return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
483
+ };
484
+ var PeriodicalExecuter = Class.create({
485
+ initialize: function(callback, frequency) {
486
+ this.callback = callback;
487
+ this.frequency = frequency;
488
+ this.currentlyExecuting = false;
489
+
490
+ this.registerCallback();
491
+ },
492
+
493
+ registerCallback: function() {
494
+ this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
495
+ },
496
+
497
+ execute: function() {
498
+ this.callback(this);
499
+ },
500
+
501
+ stop: function() {
502
+ if (!this.timer) return;
503
+ clearInterval(this.timer);
504
+ this.timer = null;
505
+ },
506
+
507
+ onTimerEvent: function() {
508
+ if (!this.currentlyExecuting) {
509
+ try {
510
+ this.currentlyExecuting = true;
511
+ this.execute();
512
+ this.currentlyExecuting = false;
513
+ } catch(e) {
514
+ this.currentlyExecuting = false;
515
+ throw e;
516
+ }
517
+ }
518
+ }
519
+ });
520
+ Object.extend(String, {
521
+ interpret: function(value) {
522
+ return value == null ? '' : String(value);
523
+ },
524
+ specialChar: {
525
+ '\b': '\\b',
526
+ '\t': '\\t',
527
+ '\n': '\\n',
528
+ '\f': '\\f',
529
+ '\r': '\\r',
530
+ '\\': '\\\\'
531
+ }
532
+ });
533
+
534
+ Object.extend(String.prototype, (function() {
535
+ var NATIVE_JSON_PARSE_SUPPORT = window.JSON &&
536
+ typeof JSON.parse === 'function' &&
537
+ JSON.parse('{"test": true}').test;
538
+
539
+ function prepareReplacement(replacement) {
540
+ if (Object.isFunction(replacement)) return replacement;
541
+ var template = new Template(replacement);
542
+ return function(match) { return template.evaluate(match) };
543
+ }
544
+
545
+ function gsub(pattern, replacement) {
546
+ var result = '', source = this, match;
547
+ replacement = prepareReplacement(replacement);
548
+
549
+ if (Object.isString(pattern))
550
+ pattern = RegExp.escape(pattern);
551
+
552
+ if (!(pattern.length || pattern.source)) {
553
+ replacement = replacement('');
554
+ return replacement + source.split('').join(replacement) + replacement;
555
+ }
556
+
557
+ while (source.length > 0) {
558
+ if (match = source.match(pattern)) {
559
+ result += source.slice(0, match.index);
560
+ result += String.interpret(replacement(match));
561
+ source = source.slice(match.index + match[0].length);
562
+ } else {
563
+ result += source, source = '';
564
+ }
565
+ }
566
+ return result;
567
+ }
568
+
569
+ function sub(pattern, replacement, count) {
570
+ replacement = prepareReplacement(replacement);
571
+ count = Object.isUndefined(count) ? 1 : count;
572
+
573
+ return this.gsub(pattern, function(match) {
574
+ if (--count < 0) return match[0];
575
+ return replacement(match);
576
+ });
577
+ }
578
+
579
+ function scan(pattern, iterator) {
580
+ this.gsub(pattern, iterator);
581
+ return String(this);
582
+ }
583
+
584
+ function truncate(length, truncation) {
585
+ length = length || 30;
586
+ truncation = Object.isUndefined(truncation) ? '...' : truncation;
587
+ return this.length > length ?
588
+ this.slice(0, length - truncation.length) + truncation : String(this);
589
+ }
590
+
591
+ function strip() {
592
+ return this.replace(/^\s+/, '').replace(/\s+$/, '');
593
+ }
594
+
595
+ function stripTags() {
596
+ return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi, '');
597
+ }
598
+
599
+ function stripScripts() {
600
+ return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
601
+ }
602
+
603
+ function extractScripts() {
604
+ var matchAll = new RegExp(Prototype.ScriptFragment, 'img'),
605
+ matchOne = new RegExp(Prototype.ScriptFragment, 'im');
606
+ return (this.match(matchAll) || []).map(function(scriptTag) {
607
+ return (scriptTag.match(matchOne) || ['', ''])[1];
608
+ });
609
+ }
610
+
611
+ function evalScripts() {
612
+ return this.extractScripts().map(function(script) { return eval(script) });
613
+ }
614
+
615
+ function escapeHTML() {
616
+ return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
617
+ }
618
+
619
+ function unescapeHTML() {
620
+ return this.stripTags().replace(/&lt;/g,'<').replace(/&gt;/g,'>').replace(/&amp;/g,'&');
621
+ }
622
+
623
+
624
+ function toQueryParams(separator) {
625
+ var match = this.strip().match(/([^?#]*)(#.*)?$/);
626
+ if (!match) return { };
627
+
628
+ return match[1].split(separator || '&').inject({ }, function(hash, pair) {
629
+ if ((pair = pair.split('='))[0]) {
630
+ var key = decodeURIComponent(pair.shift()),
631
+ value = pair.length > 1 ? pair.join('=') : pair[0];
632
+
633
+ if (value != undefined) value = decodeURIComponent(value);
634
+
635
+ if (key in hash) {
636
+ if (!Object.isArray(hash[key])) hash[key] = [hash[key]];
637
+ hash[key].push(value);
638
+ }
639
+ else hash[key] = value;
640
+ }
641
+ return hash;
642
+ });
643
+ }
644
+
645
+ function toArray() {
646
+ return this.split('');
647
+ }
648
+
649
+ function succ() {
650
+ return this.slice(0, this.length - 1) +
651
+ String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
652
+ }
653
+
654
+ function times(count) {
655
+ return count < 1 ? '' : new Array(count + 1).join(this);
656
+ }
657
+
658
+ function camelize() {
659
+ return this.replace(/-+(.)?/g, function(match, chr) {
660
+ return chr ? chr.toUpperCase() : '';
661
+ });
662
+ }
663
+
664
+ function capitalize() {
665
+ return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
666
+ }
667
+
668
+ function underscore() {
669
+ return this.replace(/::/g, '/')
670
+ .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
671
+ .replace(/([a-z\d])([A-Z])/g, '$1_$2')
672
+ .replace(/-/g, '_')
673
+ .toLowerCase();
674
+ }
675
+
676
+ function dasherize() {
677
+ return this.replace(/_/g, '-');
678
+ }
679
+
680
+ function inspect(useDoubleQuotes) {
681
+ var escapedString = this.replace(/[\x00-\x1f\\]/g, function(character) {
682
+ if (character in String.specialChar) {
683
+ return String.specialChar[character];
684
+ }
685
+ return '\\u00' + character.charCodeAt().toPaddedString(2, 16);
686
+ });
687
+ if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
688
+ return "'" + escapedString.replace(/'/g, '\\\'') + "'";
689
+ }
690
+
691
+ function unfilterJSON(filter) {
692
+ return this.replace(filter || Prototype.JSONFilter, '$1');
693
+ }
694
+
695
+ function isJSON() {
696
+ var str = this;
697
+ if (str.blank()) return false;
698
+ str = str.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@');
699
+ str = str.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']');
700
+ str = str.replace(/(?:^|:|,)(?:\s*\[)+/g, '');
701
+ return (/^[\],:{}\s]*$/).test(str);
702
+ }
703
+
704
+ function evalJSON(sanitize) {
705
+ var json = this.unfilterJSON(),
706
+ cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
707
+ if (cx.test(json)) {
708
+ json = json.replace(cx, function (a) {
709
+ return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
710
+ });
711
+ }
712
+ try {
713
+ if (!sanitize || json.isJSON()) return eval('(' + json + ')');
714
+ } catch (e) { }
715
+ throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
716
+ }
717
+
718
+ function parseJSON() {
719
+ var json = this.unfilterJSON();
720
+ return JSON.parse(json);
721
+ }
722
+
723
+ function include(pattern) {
724
+ return this.indexOf(pattern) > -1;
725
+ }
726
+
727
+ function startsWith(pattern) {
728
+ return this.lastIndexOf(pattern, 0) === 0;
729
+ }
730
+
731
+ function endsWith(pattern) {
732
+ var d = this.length - pattern.length;
733
+ return d >= 0 && this.indexOf(pattern, d) === d;
734
+ }
735
+
736
+ function empty() {
737
+ return this == '';
738
+ }
739
+
740
+ function blank() {
741
+ return /^\s*$/.test(this);
742
+ }
743
+
744
+ function interpolate(object, pattern) {
745
+ return new Template(this, pattern).evaluate(object);
746
+ }
747
+
748
+ return {
749
+ gsub: gsub,
750
+ sub: sub,
751
+ scan: scan,
752
+ truncate: truncate,
753
+ strip: String.prototype.trim || strip,
754
+ stripTags: stripTags,
755
+ stripScripts: stripScripts,
756
+ extractScripts: extractScripts,
757
+ evalScripts: evalScripts,
758
+ escapeHTML: escapeHTML,
759
+ unescapeHTML: unescapeHTML,
760
+ toQueryParams: toQueryParams,
761
+ parseQuery: toQueryParams,
762
+ toArray: toArray,
763
+ succ: succ,
764
+ times: times,
765
+ camelize: camelize,
766
+ capitalize: capitalize,
767
+ underscore: underscore,
768
+ dasherize: dasherize,
769
+ inspect: inspect,
770
+ unfilterJSON: unfilterJSON,
771
+ isJSON: isJSON,
772
+ evalJSON: NATIVE_JSON_PARSE_SUPPORT ? parseJSON : evalJSON,
773
+ include: include,
774
+ startsWith: startsWith,
775
+ endsWith: endsWith,
776
+ empty: empty,
777
+ blank: blank,
778
+ interpolate: interpolate
779
+ };
780
+ })());
781
+
782
+ var Template = Class.create({
783
+ initialize: function(template, pattern) {
784
+ this.template = template.toString();
785
+ this.pattern = pattern || Template.Pattern;
786
+ },
787
+
788
+ evaluate: function(object) {
789
+ if (object && Object.isFunction(object.toTemplateReplacements))
790
+ object = object.toTemplateReplacements();
791
+
792
+ return this.template.gsub(this.pattern, function(match) {
793
+ if (object == null) return (match[1] + '');
794
+
795
+ var before = match[1] || '';
796
+ if (before == '\\') return match[2];
797
+
798
+ var ctx = object, expr = match[3],
799
+ pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
800
+
801
+ match = pattern.exec(expr);
802
+ if (match == null) return before;
803
+
804
+ while (match != null) {
805
+ var comp = match[1].startsWith('[') ? match[2].replace(/\\\\]/g, ']') : match[1];
806
+ ctx = ctx[comp];
807
+ if (null == ctx || '' == match[3]) break;
808
+ expr = expr.substring('[' == match[3] ? match[1].length : match[0].length);
809
+ match = pattern.exec(expr);
810
+ }
811
+
812
+ return before + String.interpret(ctx);
813
+ });
814
+ }
815
+ });
816
+ Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
817
+
818
+ var $break = { };
819
+
820
+ var Enumerable = (function() {
821
+ function each(iterator, context) {
822
+ var index = 0;
823
+ try {
824
+ this._each(function(value) {
825
+ iterator.call(context, value, index++);
826
+ });
827
+ } catch (e) {
828
+ if (e != $break) throw e;
829
+ }
830
+ return this;
831
+ }
832
+
833
+ function eachSlice(number, iterator, context) {
834
+ var index = -number, slices = [], array = this.toArray();
835
+ if (number < 1) return array;
836
+ while ((index += number) < array.length)
837
+ slices.push(array.slice(index, index+number));
838
+ return slices.collect(iterator, context);
839
+ }
840
+
841
+ function all(iterator, context) {
842
+ iterator = iterator || Prototype.K;
843
+ var result = true;
844
+ this.each(function(value, index) {
845
+ result = result && !!iterator.call(context, value, index);
846
+ if (!result) throw $break;
847
+ });
848
+ return result;
849
+ }
850
+
851
+ function any(iterator, context) {
852
+ iterator = iterator || Prototype.K;
853
+ var result = false;
854
+ this.each(function(value, index) {
855
+ if (result = !!iterator.call(context, value, index))
856
+ throw $break;
857
+ });
858
+ return result;
859
+ }
860
+
861
+ function collect(iterator, context) {
862
+ iterator = iterator || Prototype.K;
863
+ var results = [];
864
+ this.each(function(value, index) {
865
+ results.push(iterator.call(context, value, index));
866
+ });
867
+ return results;
868
+ }
869
+
870
+ function detect(iterator, context) {
871
+ var result;
872
+ this.each(function(value, index) {
873
+ if (iterator.call(context, value, index)) {
874
+ result = value;
875
+ throw $break;
876
+ }
877
+ });
878
+ return result;
879
+ }
880
+
881
+ function findAll(iterator, context) {
882
+ var results = [];
883
+ this.each(function(value, index) {
884
+ if (iterator.call(context, value, index))
885
+ results.push(value);
886
+ });
887
+ return results;
888
+ }
889
+
890
+ function grep(filter, iterator, context) {
891
+ iterator = iterator || Prototype.K;
892
+ var results = [];
893
+
894
+ if (Object.isString(filter))
895
+ filter = new RegExp(RegExp.escape(filter));
896
+
897
+ this.each(function(value, index) {
898
+ if (filter.match(value))
899
+ results.push(iterator.call(context, value, index));
900
+ });
901
+ return results;
902
+ }
903
+
904
+ function include(object) {
905
+ if (Object.isFunction(this.indexOf))
906
+ if (this.indexOf(object) != -1) return true;
907
+
908
+ var found = false;
909
+ this.each(function(value) {
910
+ if (value == object) {
911
+ found = true;
912
+ throw $break;
913
+ }
914
+ });
915
+ return found;
916
+ }
917
+
918
+ function inGroupsOf(number, fillWith) {
919
+ fillWith = Object.isUndefined(fillWith) ? null : fillWith;
920
+ return this.eachSlice(number, function(slice) {
921
+ while(slice.length < number) slice.push(fillWith);
922
+ return slice;
923
+ });
924
+ }
925
+
926
+ function inject(memo, iterator, context) {
927
+ this.each(function(value, index) {
928
+ memo = iterator.call(context, memo, value, index);
929
+ });
930
+ return memo;
931
+ }
932
+
933
+ function invoke(method) {
934
+ var args = $A(arguments).slice(1);
935
+ return this.map(function(value) {
936
+ return value[method].apply(value, args);
937
+ });
938
+ }
939
+
940
+ function max(iterator, context) {
941
+ iterator = iterator || Prototype.K;
942
+ var result;
943
+ this.each(function(value, index) {
944
+ value = iterator.call(context, value, index);
945
+ if (result == null || value >= result)
946
+ result = value;
947
+ });
948
+ return result;
949
+ }
950
+
951
+ function min(iterator, context) {
952
+ iterator = iterator || Prototype.K;
953
+ var result;
954
+ this.each(function(value, index) {
955
+ value = iterator.call(context, value, index);
956
+ if (result == null || value < result)
957
+ result = value;
958
+ });
959
+ return result;
960
+ }
961
+
962
+ function partition(iterator, context) {
963
+ iterator = iterator || Prototype.K;
964
+ var trues = [], falses = [];
965
+ this.each(function(value, index) {
966
+ (iterator.call(context, value, index) ?
967
+ trues : falses).push(value);
968
+ });
969
+ return [trues, falses];
970
+ }
971
+
972
+ function pluck(property) {
973
+ var results = [];
974
+ this.each(function(value) {
975
+ results.push(value[property]);
976
+ });
977
+ return results;
978
+ }
979
+
980
+ function reject(iterator, context) {
981
+ var results = [];
982
+ this.each(function(value, index) {
983
+ if (!iterator.call(context, value, index))
984
+ results.push(value);
985
+ });
986
+ return results;
987
+ }
988
+
989
+ function sortBy(iterator, context) {
990
+ return this.map(function(value, index) {
991
+ return {
992
+ value: value,
993
+ criteria: iterator.call(context, value, index)
994
+ };
995
+ }).sort(function(left, right) {
996
+ var a = left.criteria, b = right.criteria;
997
+ return a < b ? -1 : a > b ? 1 : 0;
998
+ }).pluck('value');
999
+ }
1000
+
1001
+ function toArray() {
1002
+ return this.map();
1003
+ }
1004
+
1005
+ function zip() {
1006
+ var iterator = Prototype.K, args = $A(arguments);
1007
+ if (Object.isFunction(args.last()))
1008
+ iterator = args.pop();
1009
+
1010
+ var collections = [this].concat(args).map($A);
1011
+ return this.map(function(value, index) {
1012
+ return iterator(collections.pluck(index));
1013
+ });
1014
+ }
1015
+
1016
+ function size() {
1017
+ return this.toArray().length;
1018
+ }
1019
+
1020
+ function inspect() {
1021
+ return '#<Enumerable:' + this.toArray().inspect() + '>';
1022
+ }
1023
+
1024
+
1025
+
1026
+
1027
+
1028
+
1029
+
1030
+
1031
+
1032
+ return {
1033
+ each: each,
1034
+ eachSlice: eachSlice,
1035
+ all: all,
1036
+ every: all,
1037
+ any: any,
1038
+ some: any,
1039
+ collect: collect,
1040
+ map: collect,
1041
+ detect: detect,
1042
+ findAll: findAll,
1043
+ select: findAll,
1044
+ filter: findAll,
1045
+ grep: grep,
1046
+ include: include,
1047
+ member: include,
1048
+ inGroupsOf: inGroupsOf,
1049
+ inject: inject,
1050
+ invoke: invoke,
1051
+ max: max,
1052
+ min: min,
1053
+ partition: partition,
1054
+ pluck: pluck,
1055
+ reject: reject,
1056
+ sortBy: sortBy,
1057
+ toArray: toArray,
1058
+ entries: toArray,
1059
+ zip: zip,
1060
+ size: size,
1061
+ inspect: inspect,
1062
+ find: detect
1063
+ };
1064
+ })();
1065
+
1066
+ function $A(iterable) {
1067
+ if (!iterable) return [];
1068
+ if ('toArray' in Object(iterable)) return iterable.toArray();
1069
+ var length = iterable.length || 0, results = new Array(length);
1070
+ while (length--) results[length] = iterable[length];
1071
+ return results;
1072
+ }
1073
+
1074
+
1075
+ function $w(string) {
1076
+ if (!Object.isString(string)) return [];
1077
+ string = string.strip();
1078
+ return string ? string.split(/\s+/) : [];
1079
+ }
1080
+
1081
+ Array.from = $A;
1082
+
1083
+
1084
+ (function() {
1085
+ var arrayProto = Array.prototype,
1086
+ slice = arrayProto.slice,
1087
+ _each = arrayProto.forEach; // use native browser JS 1.6 implementation if available
1088
+
1089
+ function each(iterator, context) {
1090
+ for (var i = 0, length = this.length >>> 0; i < length; i++) {
1091
+ if (i in this) iterator.call(context, this[i], i, this);
1092
+ }
1093
+ }
1094
+ if (!_each) _each = each;
1095
+
1096
+ function clear() {
1097
+ this.length = 0;
1098
+ return this;
1099
+ }
1100
+
1101
+ function first() {
1102
+ return this[0];
1103
+ }
1104
+
1105
+ function last() {
1106
+ return this[this.length - 1];
1107
+ }
1108
+
1109
+ function compact() {
1110
+ return this.select(function(value) {
1111
+ return value != null;
1112
+ });
1113
+ }
1114
+
1115
+ function flatten() {
1116
+ return this.inject([], function(array, value) {
1117
+ if (Object.isArray(value))
1118
+ return array.concat(value.flatten());
1119
+ array.push(value);
1120
+ return array;
1121
+ });
1122
+ }
1123
+
1124
+ function without() {
1125
+ var values = slice.call(arguments, 0);
1126
+ return this.select(function(value) {
1127
+ return !values.include(value);
1128
+ });
1129
+ }
1130
+
1131
+ function reverse(inline) {
1132
+ return (inline === false ? this.toArray() : this)._reverse();
1133
+ }
1134
+
1135
+ function uniq(sorted) {
1136
+ return this.inject([], function(array, value, index) {
1137
+ if (0 == index || (sorted ? array.last() != value : !array.include(value)))
1138
+ array.push(value);
1139
+ return array;
1140
+ });
1141
+ }
1142
+
1143
+ function intersect(array) {
1144
+ return this.uniq().findAll(function(item) {
1145
+ return array.detect(function(value) { return item === value });
1146
+ });
1147
+ }
1148
+
1149
+
1150
+ function clone() {
1151
+ return slice.call(this, 0);
1152
+ }
1153
+
1154
+ function size() {
1155
+ return this.length;
1156
+ }
1157
+
1158
+ function inspect() {
1159
+ return '[' + this.map(Object.inspect).join(', ') + ']';
1160
+ }
1161
+
1162
+ function indexOf(item, i) {
1163
+ i || (i = 0);
1164
+ var length = this.length;
1165
+ if (i < 0) i = length + i;
1166
+ for (; i < length; i++)
1167
+ if (this[i] === item) return i;
1168
+ return -1;
1169
+ }
1170
+
1171
+ function lastIndexOf(item, i) {
1172
+ i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1;
1173
+ var n = this.slice(0, i).reverse().indexOf(item);
1174
+ return (n < 0) ? n : i - n - 1;
1175
+ }
1176
+
1177
+ function concat() {
1178
+ var array = slice.call(this, 0), item;
1179
+ for (var i = 0, length = arguments.length; i < length; i++) {
1180
+ item = arguments[i];
1181
+ if (Object.isArray(item) && !('callee' in item)) {
1182
+ for (var j = 0, arrayLength = item.length; j < arrayLength; j++)
1183
+ array.push(item[j]);
1184
+ } else {
1185
+ array.push(item);
1186
+ }
1187
+ }
1188
+ return array;
1189
+ }
1190
+
1191
+ Object.extend(arrayProto, Enumerable);
1192
+
1193
+ if (!arrayProto._reverse)
1194
+ arrayProto._reverse = arrayProto.reverse;
1195
+
1196
+ Object.extend(arrayProto, {
1197
+ _each: _each,
1198
+ clear: clear,
1199
+ first: first,
1200
+ last: last,
1201
+ compact: compact,
1202
+ flatten: flatten,
1203
+ without: without,
1204
+ reverse: reverse,
1205
+ uniq: uniq,
1206
+ intersect: intersect,
1207
+ clone: clone,
1208
+ toArray: clone,
1209
+ size: size,
1210
+ inspect: inspect
1211
+ });
1212
+
1213
+ var CONCAT_ARGUMENTS_BUGGY = (function() {
1214
+ return [].concat(arguments)[0][0] !== 1;
1215
+ })(1,2)
1216
+
1217
+ if (CONCAT_ARGUMENTS_BUGGY) arrayProto.concat = concat;
1218
+
1219
+ if (!arrayProto.indexOf) arrayProto.indexOf = indexOf;
1220
+ if (!arrayProto.lastIndexOf) arrayProto.lastIndexOf = lastIndexOf;
1221
+ })();
1222
+ function $H(object) {
1223
+ return new Hash(object);
1224
+ };
1225
+
1226
+ var Hash = Class.create(Enumerable, (function() {
1227
+ function initialize(object) {
1228
+ this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
1229
+ }
1230
+
1231
+
1232
+ function _each(iterator) {
1233
+ for (var key in this._object) {
1234
+ var value = this._object[key], pair = [key, value];
1235
+ pair.key = key;
1236
+ pair.value = value;
1237
+ iterator(pair);
1238
+ }
1239
+ }
1240
+
1241
+ function set(key, value) {
1242
+ return this._object[key] = value;
1243
+ }
1244
+
1245
+ function get(key) {
1246
+ if (this._object[key] !== Object.prototype[key])
1247
+ return this._object[key];
1248
+ }
1249
+
1250
+ function unset(key) {
1251
+ var value = this._object[key];
1252
+ delete this._object[key];
1253
+ return value;
1254
+ }
1255
+
1256
+ function toObject() {
1257
+ return Object.clone(this._object);
1258
+ }
1259
+
1260
+
1261
+
1262
+ function keys() {
1263
+ return this.pluck('key');
1264
+ }
1265
+
1266
+ function values() {
1267
+ return this.pluck('value');
1268
+ }
1269
+
1270
+ function index(value) {
1271
+ var match = this.detect(function(pair) {
1272
+ return pair.value === value;
1273
+ });
1274
+ return match && match.key;
1275
+ }
1276
+
1277
+ function merge(object) {
1278
+ return this.clone().update(object);
1279
+ }
1280
+
1281
+ function update(object) {
1282
+ return new Hash(object).inject(this, function(result, pair) {
1283
+ result.set(pair.key, pair.value);
1284
+ return result;
1285
+ });
1286
+ }
1287
+
1288
+ function toQueryPair(key, value) {
1289
+ if (Object.isUndefined(value)) return key;
1290
+ return key + '=' + encodeURIComponent(String.interpret(value));
1291
+ }
1292
+
1293
+ function toQueryString() {
1294
+ return this.inject([], function(results, pair) {
1295
+ var key = encodeURIComponent(pair.key), values = pair.value;
1296
+
1297
+ if (values && typeof values == 'object') {
1298
+ if (Object.isArray(values)) {
1299
+ var queryValues = [];
1300
+ for (var i = 0, len = values.length, value; i < len; i++) {
1301
+ value = values[i];
1302
+ queryValues.push(toQueryPair(key, value));
1303
+ }
1304
+ return results.concat(queryValues);
1305
+ }
1306
+ } else results.push(toQueryPair(key, values));
1307
+ return results;
1308
+ }).join('&');
1309
+ }
1310
+
1311
+ function inspect() {
1312
+ return '#<Hash:{' + this.map(function(pair) {
1313
+ return pair.map(Object.inspect).join(': ');
1314
+ }).join(', ') + '}>';
1315
+ }
1316
+
1317
+ function clone() {
1318
+ return new Hash(this);
1319
+ }
1320
+
1321
+ return {
1322
+ initialize: initialize,
1323
+ _each: _each,
1324
+ set: set,
1325
+ get: get,
1326
+ unset: unset,
1327
+ toObject: toObject,
1328
+ toTemplateReplacements: toObject,
1329
+ keys: keys,
1330
+ values: values,
1331
+ index: index,
1332
+ merge: merge,
1333
+ update: update,
1334
+ toQueryString: toQueryString,
1335
+ inspect: inspect,
1336
+ toJSON: toObject,
1337
+ clone: clone
1338
+ };
1339
+ })());
1340
+
1341
+ Hash.from = $H;
1342
+ Object.extend(Number.prototype, (function() {
1343
+ function toColorPart() {
1344
+ return this.toPaddedString(2, 16);
1345
+ }
1346
+
1347
+ function succ() {
1348
+ return this + 1;
1349
+ }
1350
+
1351
+ function times(iterator, context) {
1352
+ $R(0, this, true).each(iterator, context);
1353
+ return this;
1354
+ }
1355
+
1356
+ function toPaddedString(length, radix) {
1357
+ var string = this.toString(radix || 10);
1358
+ return '0'.times(length - string.length) + string;
1359
+ }
1360
+
1361
+ function abs() {
1362
+ return Math.abs(this);
1363
+ }
1364
+
1365
+ function round() {
1366
+ return Math.round(this);
1367
+ }
1368
+
1369
+ function ceil() {
1370
+ return Math.ceil(this);
1371
+ }
1372
+
1373
+ function floor() {
1374
+ return Math.floor(this);
1375
+ }
1376
+
1377
+ return {
1378
+ toColorPart: toColorPart,
1379
+ succ: succ,
1380
+ times: times,
1381
+ toPaddedString: toPaddedString,
1382
+ abs: abs,
1383
+ round: round,
1384
+ ceil: ceil,
1385
+ floor: floor
1386
+ };
1387
+ })());
1388
+
1389
+ function $R(start, end, exclusive) {
1390
+ return new ObjectRange(start, end, exclusive);
1391
+ }
1392
+
1393
+ var ObjectRange = Class.create(Enumerable, (function() {
1394
+ function initialize(start, end, exclusive) {
1395
+ this.start = start;
1396
+ this.end = end;
1397
+ this.exclusive = exclusive;
1398
+ }
1399
+
1400
+ function _each(iterator) {
1401
+ var value = this.start;
1402
+ while (this.include(value)) {
1403
+ iterator(value);
1404
+ value = value.succ();
1405
+ }
1406
+ }
1407
+
1408
+ function include(value) {
1409
+ if (value < this.start)
1410
+ return false;
1411
+ if (this.exclusive)
1412
+ return value < this.end;
1413
+ return value <= this.end;
1414
+ }
1415
+
1416
+ return {
1417
+ initialize: initialize,
1418
+ _each: _each,
1419
+ include: include
1420
+ };
1421
+ })());
1422
+
1423
+
1424
+
1425
+ var Ajax = {
1426
+ getTransport: function() {
1427
+ return Try.these(
1428
+ function() {return new XMLHttpRequest()},
1429
+ function() {return new ActiveXObject('Msxml2.XMLHTTP')},
1430
+ function() {return new ActiveXObject('Microsoft.XMLHTTP')}
1431
+ ) || false;
1432
+ },
1433
+
1434
+ activeRequestCount: 0
1435
+ };
1436
+
1437
+ Ajax.Responders = {
1438
+ responders: [],
1439
+
1440
+ _each: function(iterator) {
1441
+ this.responders._each(iterator);
1442
+ },
1443
+
1444
+ register: function(responder) {
1445
+ if (!this.include(responder))
1446
+ this.responders.push(responder);
1447
+ },
1448
+
1449
+ unregister: function(responder) {
1450
+ this.responders = this.responders.without(responder);
1451
+ },
1452
+
1453
+ dispatch: function(callback, request, transport, json) {
1454
+ this.each(function(responder) {
1455
+ if (Object.isFunction(responder[callback])) {
1456
+ try {
1457
+ responder[callback].apply(responder, [request, transport, json]);
1458
+ } catch (e) { }
1459
+ }
1460
+ });
1461
+ }
1462
+ };
1463
+
1464
+ Object.extend(Ajax.Responders, Enumerable);
1465
+
1466
+ Ajax.Responders.register({
1467
+ onCreate: function() { Ajax.activeRequestCount++ },
1468
+ onComplete: function() { Ajax.activeRequestCount-- }
1469
+ });
1470
+ Ajax.Base = Class.create({
1471
+ initialize: function(options) {
1472
+ this.options = {
1473
+ method: 'post',
1474
+ asynchronous: true,
1475
+ contentType: 'application/x-www-form-urlencoded',
1476
+ encoding: 'UTF-8',
1477
+ parameters: '',
1478
+ evalJSON: true,
1479
+ evalJS: true
1480
+ };
1481
+ Object.extend(this.options, options || { });
1482
+
1483
+ this.options.method = this.options.method.toLowerCase();
1484
+
1485
+ if (Object.isHash(this.options.parameters))
1486
+ this.options.parameters = this.options.parameters.toObject();
1487
+ }
1488
+ });
1489
+ Ajax.Request = Class.create(Ajax.Base, {
1490
+ _complete: false,
1491
+
1492
+ initialize: function($super, url, options) {
1493
+ $super(options);
1494
+ this.transport = Ajax.getTransport();
1495
+ this.request(url);
1496
+ },
1497
+
1498
+ request: function(url) {
1499
+ this.url = url;
1500
+ this.method = this.options.method;
1501
+ var params = Object.isString(this.options.parameters) ?
1502
+ this.options.parameters :
1503
+ Object.toQueryString(this.options.parameters);
1504
+
1505
+ if (!['get', 'post'].include(this.method)) {
1506
+ params += (params ? '&' : '') + "_method=" + this.method;
1507
+ this.method = 'post';
1508
+ }
1509
+
1510
+ if (params && this.method === 'get') {
1511
+ this.url += (this.url.include('?') ? '&' : '?') + params;
1512
+ }
1513
+
1514
+ this.parameters = params.toQueryParams();
1515
+
1516
+ try {
1517
+ var response = new Ajax.Response(this);
1518
+ if (this.options.onCreate) this.options.onCreate(response);
1519
+ Ajax.Responders.dispatch('onCreate', this, response);
1520
+
1521
+ this.transport.open(this.method.toUpperCase(), this.url,
1522
+ this.options.asynchronous);
1523
+
1524
+ if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1);
1525
+
1526
+ this.transport.onreadystatechange = this.onStateChange.bind(this);
1527
+ this.setRequestHeaders();
1528
+
1529
+ this.body = this.method == 'post' ? (this.options.postBody || params) : null;
1530
+ this.transport.send(this.body);
1531
+
1532
+ /* Force Firefox to handle ready state 4 for synchronous requests */
1533
+ if (!this.options.asynchronous && this.transport.overrideMimeType)
1534
+ this.onStateChange();
1535
+
1536
+ }
1537
+ catch (e) {
1538
+ this.dispatchException(e);
1539
+ }
1540
+ },
1541
+
1542
+ onStateChange: function() {
1543
+ var readyState = this.transport.readyState;
1544
+ if (readyState > 1 && !((readyState == 4) && this._complete))
1545
+ this.respondToReadyState(this.transport.readyState);
1546
+ },
1547
+
1548
+ setRequestHeaders: function() {
1549
+ var headers = {
1550
+ 'X-Requested-With': 'XMLHttpRequest',
1551
+ 'X-Prototype-Version': Prototype.Version,
1552
+ 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
1553
+ };
1554
+
1555
+ if (this.method == 'post') {
1556
+ headers['Content-type'] = this.options.contentType +
1557
+ (this.options.encoding ? '; charset=' + this.options.encoding : '');
1558
+
1559
+ /* Force "Connection: close" for older Mozilla browsers to work
1560
+ * around a bug where XMLHttpRequest sends an incorrect
1561
+ * Content-length header. See Mozilla Bugzilla #246651.
1562
+ */
1563
+ if (this.transport.overrideMimeType &&
1564
+ (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
1565
+ headers['Connection'] = 'close';
1566
+ }
1567
+
1568
+ if (typeof this.options.requestHeaders == 'object') {
1569
+ var extras = this.options.requestHeaders;
1570
+
1571
+ if (Object.isFunction(extras.push))
1572
+ for (var i = 0, length = extras.length; i < length; i += 2)
1573
+ headers[extras[i]] = extras[i+1];
1574
+ else
1575
+ $H(extras).each(function(pair) { headers[pair.key] = pair.value });
1576
+ }
1577
+
1578
+ for (var name in headers)
1579
+ this.transport.setRequestHeader(name, headers[name]);
1580
+ },
1581
+
1582
+ success: function() {
1583
+ var status = this.getStatus();
1584
+ return !status || (status >= 200 && status < 300) || status == 304;
1585
+ },
1586
+
1587
+ getStatus: function() {
1588
+ try {
1589
+ if (this.transport.status === 1223) return 204;
1590
+ return this.transport.status || 0;
1591
+ } catch (e) { return 0 }
1592
+ },
1593
+
1594
+ respondToReadyState: function(readyState) {
1595
+ var state = Ajax.Request.Events[readyState], response = new Ajax.Response(this);
1596
+
1597
+ if (state == 'Complete') {
1598
+ try {
1599
+ this._complete = true;
1600
+ (this.options['on' + response.status]
1601
+ || this.options['on' + (this.success() ? 'Success' : 'Failure')]
1602
+ || Prototype.emptyFunction)(response, response.headerJSON);
1603
+ } catch (e) {
1604
+ this.dispatchException(e);
1605
+ }
1606
+
1607
+ var contentType = response.getHeader('Content-type');
1608
+ if (this.options.evalJS == 'force'
1609
+ || (this.options.evalJS && this.isSameOrigin() && contentType
1610
+ && contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i)))
1611
+ this.evalResponse();
1612
+ }
1613
+
1614
+ try {
1615
+ (this.options['on' + state] || Prototype.emptyFunction)(response, response.headerJSON);
1616
+ Ajax.Responders.dispatch('on' + state, this, response, response.headerJSON);
1617
+ } catch (e) {
1618
+ this.dispatchException(e);
1619
+ }
1620
+
1621
+ if (state == 'Complete') {
1622
+ this.transport.onreadystatechange = Prototype.emptyFunction;
1623
+ }
1624
+ },
1625
+
1626
+ isSameOrigin: function() {
1627
+ var m = this.url.match(/^\s*https?:\/\/[^\/]*/);
1628
+ return !m || (m[0] == '#{protocol}//#{domain}#{port}'.interpolate({
1629
+ protocol: location.protocol,
1630
+ domain: document.domain,
1631
+ port: location.port ? ':' + location.port : ''
1632
+ }));
1633
+ },
1634
+
1635
+ getHeader: function(name) {
1636
+ try {
1637
+ return this.transport.getResponseHeader(name) || null;
1638
+ } catch (e) { return null; }
1639
+ },
1640
+
1641
+ evalResponse: function() {
1642
+ try {
1643
+ return eval((this.transport.responseText || '').unfilterJSON());
1644
+ } catch (e) {
1645
+ this.dispatchException(e);
1646
+ }
1647
+ },
1648
+
1649
+ dispatchException: function(exception) {
1650
+ (this.options.onException || Prototype.emptyFunction)(this, exception);
1651
+ Ajax.Responders.dispatch('onException', this, exception);
1652
+ }
1653
+ });
1654
+
1655
+ Ajax.Request.Events =
1656
+ ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
1657
+
1658
+
1659
+
1660
+
1661
+
1662
+
1663
+
1664
+
1665
+ Ajax.Response = Class.create({
1666
+ initialize: function(request){
1667
+ this.request = request;
1668
+ var transport = this.transport = request.transport,
1669
+ readyState = this.readyState = transport.readyState;
1670
+
1671
+ if ((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) {
1672
+ this.status = this.getStatus();
1673
+ this.statusText = this.getStatusText();
1674
+ this.responseText = String.interpret(transport.responseText);
1675
+ this.headerJSON = this._getHeaderJSON();
1676
+ }
1677
+
1678
+ if (readyState == 4) {
1679
+ var xml = transport.responseXML;
1680
+ this.responseXML = Object.isUndefined(xml) ? null : xml;
1681
+ this.responseJSON = this._getResponseJSON();
1682
+ }
1683
+ },
1684
+
1685
+ status: 0,
1686
+
1687
+ statusText: '',
1688
+
1689
+ getStatus: Ajax.Request.prototype.getStatus,
1690
+
1691
+ getStatusText: function() {
1692
+ try {
1693
+ return this.transport.statusText || '';
1694
+ } catch (e) { return '' }
1695
+ },
1696
+
1697
+ getHeader: Ajax.Request.prototype.getHeader,
1698
+
1699
+ getAllHeaders: function() {
1700
+ try {
1701
+ return this.getAllResponseHeaders();
1702
+ } catch (e) { return null }
1703
+ },
1704
+
1705
+ getResponseHeader: function(name) {
1706
+ return this.transport.getResponseHeader(name);
1707
+ },
1708
+
1709
+ getAllResponseHeaders: function() {
1710
+ return this.transport.getAllResponseHeaders();
1711
+ },
1712
+
1713
+ _getHeaderJSON: function() {
1714
+ var json = this.getHeader('X-JSON');
1715
+ if (!json) return null;
1716
+ json = decodeURIComponent(escape(json));
1717
+ try {
1718
+ return json.evalJSON(this.request.options.sanitizeJSON ||
1719
+ !this.request.isSameOrigin());
1720
+ } catch (e) {
1721
+ this.request.dispatchException(e);
1722
+ }
1723
+ },
1724
+
1725
+ _getResponseJSON: function() {
1726
+ var options = this.request.options;
1727
+ if (!options.evalJSON || (options.evalJSON != 'force' &&
1728
+ !(this.getHeader('Content-type') || '').include('application/json')) ||
1729
+ this.responseText.blank())
1730
+ return null;
1731
+ try {
1732
+ return this.responseText.evalJSON(options.sanitizeJSON ||
1733
+ !this.request.isSameOrigin());
1734
+ } catch (e) {
1735
+ this.request.dispatchException(e);
1736
+ }
1737
+ }
1738
+ });
1739
+
1740
+ Ajax.Updater = Class.create(Ajax.Request, {
1741
+ initialize: function($super, container, url, options) {
1742
+ this.container = {
1743
+ success: (container.success || container),
1744
+ failure: (container.failure || (container.success ? null : container))
1745
+ };
1746
+
1747
+ options = Object.clone(options);
1748
+ var onComplete = options.onComplete;
1749
+ options.onComplete = (function(response, json) {
1750
+ this.updateContent(response.responseText);
1751
+ if (Object.isFunction(onComplete)) onComplete(response, json);
1752
+ }).bind(this);
1753
+
1754
+ $super(url, options);
1755
+ },
1756
+
1757
+ updateContent: function(responseText) {
1758
+ var receiver = this.container[this.success() ? 'success' : 'failure'],
1759
+ options = this.options;
1760
+
1761
+ if (!options.evalScripts) responseText = responseText.stripScripts();
1762
+
1763
+ if (receiver = $(receiver)) {
1764
+ if (options.insertion) {
1765
+ if (Object.isString(options.insertion)) {
1766
+ var insertion = { }; insertion[options.insertion] = responseText;
1767
+ receiver.insert(insertion);
1768
+ }
1769
+ else options.insertion(receiver, responseText);
1770
+ }
1771
+ else receiver.update(responseText);
1772
+ }
1773
+ }
1774
+ });
1775
+
1776
+ Ajax.PeriodicalUpdater = Class.create(Ajax.Base, {
1777
+ initialize: function($super, container, url, options) {
1778
+ $super(options);
1779
+ this.onComplete = this.options.onComplete;
1780
+
1781
+ this.frequency = (this.options.frequency || 2);
1782
+ this.decay = (this.options.decay || 1);
1783
+
1784
+ this.updater = { };
1785
+ this.container = container;
1786
+ this.url = url;
1787
+
1788
+ this.start();
1789
+ },
1790
+
1791
+ start: function() {
1792
+ this.options.onComplete = this.updateComplete.bind(this);
1793
+ this.onTimerEvent();
1794
+ },
1795
+
1796
+ stop: function() {
1797
+ this.updater.options.onComplete = undefined;
1798
+ clearTimeout(this.timer);
1799
+ (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
1800
+ },
1801
+
1802
+ updateComplete: function(response) {
1803
+ if (this.options.decay) {
1804
+ this.decay = (response.responseText == this.lastText ?
1805
+ this.decay * this.options.decay : 1);
1806
+
1807
+ this.lastText = response.responseText;
1808
+ }
1809
+ this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency);
1810
+ },
1811
+
1812
+ onTimerEvent: function() {
1813
+ this.updater = new Ajax.Updater(this.container, this.url, this.options);
1814
+ }
1815
+ });
1816
+
1817
+
1818
+ function $(element) {
1819
+ if (arguments.length > 1) {
1820
+ for (var i = 0, elements = [], length = arguments.length; i < length; i++)
1821
+ elements.push($(arguments[i]));
1822
+ return elements;
1823
+ }
1824
+ if (Object.isString(element))
1825
+ element = document.getElementById(element);
1826
+ return Element.extend(element);
1827
+ }
1828
+
1829
+ if (Prototype.BrowserFeatures.XPath) {
1830
+ document._getElementsByXPath = function(expression, parentElement) {
1831
+ var results = [];
1832
+ var query = document.evaluate(expression, $(parentElement) || document,
1833
+ null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
1834
+ for (var i = 0, length = query.snapshotLength; i < length; i++)
1835
+ results.push(Element.extend(query.snapshotItem(i)));
1836
+ return results;
1837
+ };
1838
+ }
1839
+
1840
+ /*--------------------------------------------------------------------------*/
1841
+
1842
+ if (!Node) var Node = { };
1843
+
1844
+ if (!Node.ELEMENT_NODE) {
1845
+ Object.extend(Node, {
1846
+ ELEMENT_NODE: 1,
1847
+ ATTRIBUTE_NODE: 2,
1848
+ TEXT_NODE: 3,
1849
+ CDATA_SECTION_NODE: 4,
1850
+ ENTITY_REFERENCE_NODE: 5,
1851
+ ENTITY_NODE: 6,
1852
+ PROCESSING_INSTRUCTION_NODE: 7,
1853
+ COMMENT_NODE: 8,
1854
+ DOCUMENT_NODE: 9,
1855
+ DOCUMENT_TYPE_NODE: 10,
1856
+ DOCUMENT_FRAGMENT_NODE: 11,
1857
+ NOTATION_NODE: 12
1858
+ });
1859
+ }
1860
+
1861
+
1862
+
1863
+ (function(global) {
1864
+ function shouldUseCache(tagName, attributes) {
1865
+ if (tagName === 'select') return false;
1866
+ if ('type' in attributes) return false;
1867
+ return true;
1868
+ }
1869
+
1870
+ var HAS_EXTENDED_CREATE_ELEMENT_SYNTAX = (function(){
1871
+ try {
1872
+ var el = document.createElement('<input name="x">');
1873
+ return el.tagName.toLowerCase() === 'input' && el.name === 'x';
1874
+ }
1875
+ catch(err) {
1876
+ return false;
1877
+ }
1878
+ })();
1879
+
1880
+ var element = global.Element;
1881
+
1882
+ global.Element = function(tagName, attributes) {
1883
+ attributes = attributes || { };
1884
+ tagName = tagName.toLowerCase();
1885
+ var cache = Element.cache;
1886
+
1887
+ if (HAS_EXTENDED_CREATE_ELEMENT_SYNTAX && attributes.name) {
1888
+ tagName = '<' + tagName + ' name="' + attributes.name + '">';
1889
+ delete attributes.name;
1890
+ return Element.writeAttribute(document.createElement(tagName), attributes);
1891
+ }
1892
+
1893
+ if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName));
1894
+
1895
+ var node = shouldUseCache(tagName, attributes) ?
1896
+ cache[tagName].cloneNode(false) : document.createElement(tagName);
1897
+
1898
+ return Element.writeAttribute(node, attributes);
1899
+ };
1900
+
1901
+ Object.extend(global.Element, element || { });
1902
+ if (element) global.Element.prototype = element.prototype;
1903
+
1904
+ })(this);
1905
+
1906
+ Element.idCounter = 1;
1907
+ Element.cache = { };
1908
+
1909
+ Element._purgeElement = function(element) {
1910
+ var uid = element._prototypeUID;
1911
+ if (uid) {
1912
+ Element.stopObserving(element);
1913
+ element._prototypeUID = void 0;
1914
+ delete Element.Storage[uid];
1915
+ }
1916
+ }
1917
+
1918
+ Element.Methods = {
1919
+ visible: function(element) {
1920
+ return $(element).style.display != 'none';
1921
+ },
1922
+
1923
+ toggle: function(element) {
1924
+ element = $(element);
1925
+ Element[Element.visible(element) ? 'hide' : 'show'](element);
1926
+ return element;
1927
+ },
1928
+
1929
+ hide: function(element) {
1930
+ element = $(element);
1931
+ element.style.display = 'none';
1932
+ return element;
1933
+ },
1934
+
1935
+ show: function(element) {
1936
+ element = $(element);
1937
+ element.style.display = '';
1938
+ return element;
1939
+ },
1940
+
1941
+ remove: function(element) {
1942
+ element = $(element);
1943
+ element.parentNode.removeChild(element);
1944
+ return element;
1945
+ },
1946
+
1947
+ update: (function(){
1948
+
1949
+ var SELECT_ELEMENT_INNERHTML_BUGGY = (function(){
1950
+ var el = document.createElement("select"),
1951
+ isBuggy = true;
1952
+ el.innerHTML = "<option value=\"test\">test</option>";
1953
+ if (el.options && el.options[0]) {
1954
+ isBuggy = el.options[0].nodeName.toUpperCase() !== "OPTION";
1955
+ }
1956
+ el = null;
1957
+ return isBuggy;
1958
+ })();
1959
+
1960
+ var TABLE_ELEMENT_INNERHTML_BUGGY = (function(){
1961
+ try {
1962
+ var el = document.createElement("table");
1963
+ if (el && el.tBodies) {
1964
+ el.innerHTML = "<tbody><tr><td>test</td></tr></tbody>";
1965
+ var isBuggy = typeof el.tBodies[0] == "undefined";
1966
+ el = null;
1967
+ return isBuggy;
1968
+ }
1969
+ } catch (e) {
1970
+ return true;
1971
+ }
1972
+ })();
1973
+
1974
+ var LINK_ELEMENT_INNERHTML_BUGGY = (function() {
1975
+ try {
1976
+ var el = document.createElement('div');
1977
+ el.innerHTML = "<link>";
1978
+ var isBuggy = (el.childNodes.length === 0);
1979
+ el = null;
1980
+ return isBuggy;
1981
+ } catch(e) {
1982
+ return true;
1983
+ }
1984
+ })();
1985
+
1986
+ var ANY_INNERHTML_BUGGY = SELECT_ELEMENT_INNERHTML_BUGGY ||
1987
+ TABLE_ELEMENT_INNERHTML_BUGGY || LINK_ELEMENT_INNERHTML_BUGGY;
1988
+
1989
+ var SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING = (function () {
1990
+ var s = document.createElement("script"),
1991
+ isBuggy = false;
1992
+ try {
1993
+ s.appendChild(document.createTextNode(""));
1994
+ isBuggy = !s.firstChild ||
1995
+ s.firstChild && s.firstChild.nodeType !== 3;
1996
+ } catch (e) {
1997
+ isBuggy = true;
1998
+ }
1999
+ s = null;
2000
+ return isBuggy;
2001
+ })();
2002
+
2003
+
2004
+ function update(element, content) {
2005
+ element = $(element);
2006
+ var purgeElement = Element._purgeElement;
2007
+
2008
+ var descendants = element.getElementsByTagName('*'),
2009
+ i = descendants.length;
2010
+ while (i--) purgeElement(descendants[i]);
2011
+
2012
+ if (content && content.toElement)
2013
+ content = content.toElement();
2014
+
2015
+ if (Object.isElement(content))
2016
+ return element.update().insert(content);
2017
+
2018
+ content = Object.toHTML(content);
2019
+
2020
+ var tagName = element.tagName.toUpperCase();
2021
+
2022
+ if (tagName === 'SCRIPT' && SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING) {
2023
+ element.text = content;
2024
+ return element;
2025
+ }
2026
+
2027
+ if (ANY_INNERHTML_BUGGY) {
2028
+ if (tagName in Element._insertionTranslations.tags) {
2029
+ while (element.firstChild) {
2030
+ element.removeChild(element.firstChild);
2031
+ }
2032
+ Element._getContentFromAnonymousElement(tagName, content.stripScripts())
2033
+ .each(function(node) {
2034
+ element.appendChild(node)
2035
+ });
2036
+ } else if (LINK_ELEMENT_INNERHTML_BUGGY && Object.isString(content) && content.indexOf('<link') > -1) {
2037
+ while (element.firstChild) {
2038
+ element.removeChild(element.firstChild);
2039
+ }
2040
+ var nodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts(), true);
2041
+ nodes.each(function(node) { element.appendChild(node) });
2042
+ }
2043
+ else {
2044
+ element.innerHTML = content.stripScripts();
2045
+ }
2046
+ }
2047
+ else {
2048
+ element.innerHTML = content.stripScripts();
2049
+ }
2050
+
2051
+ content.evalScripts.bind(content).defer();
2052
+ return element;
2053
+ }
2054
+
2055
+ return update;
2056
+ })(),
2057
+
2058
+ replace: function(element, content) {
2059
+ element = $(element);
2060
+ if (content && content.toElement) content = content.toElement();
2061
+ else if (!Object.isElement(content)) {
2062
+ content = Object.toHTML(content);
2063
+ var range = element.ownerDocument.createRange();
2064
+ range.selectNode(element);
2065
+ content.evalScripts.bind(content).defer();
2066
+ content = range.createContextualFragment(content.stripScripts());
2067
+ }
2068
+ element.parentNode.replaceChild(content, element);
2069
+ return element;
2070
+ },
2071
+
2072
+ insert: function(element, insertions) {
2073
+ element = $(element);
2074
+
2075
+ if (Object.isString(insertions) || Object.isNumber(insertions) ||
2076
+ Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML)))
2077
+ insertions = {bottom:insertions};
2078
+
2079
+ var content, insert, tagName, childNodes;
2080
+
2081
+ for (var position in insertions) {
2082
+ content = insertions[position];
2083
+ position = position.toLowerCase();
2084
+ insert = Element._insertionTranslations[position];
2085
+
2086
+ if (content && content.toElement) content = content.toElement();
2087
+ if (Object.isElement(content)) {
2088
+ insert(element, content);
2089
+ continue;
2090
+ }
2091
+
2092
+ content = Object.toHTML(content);
2093
+
2094
+ tagName = ((position == 'before' || position == 'after')
2095
+ ? element.parentNode : element).tagName.toUpperCase();
2096
+
2097
+ childNodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
2098
+
2099
+ if (position == 'top' || position == 'after') childNodes.reverse();
2100
+ childNodes.each(insert.curry(element));
2101
+
2102
+ content.evalScripts.bind(content).defer();
2103
+ }
2104
+
2105
+ return element;
2106
+ },
2107
+
2108
+ wrap: function(element, wrapper, attributes) {
2109
+ element = $(element);
2110
+ if (Object.isElement(wrapper))
2111
+ $(wrapper).writeAttribute(attributes || { });
2112
+ else if (Object.isString(wrapper)) wrapper = new Element(wrapper, attributes);
2113
+ else wrapper = new Element('div', wrapper);
2114
+ if (element.parentNode)
2115
+ element.parentNode.replaceChild(wrapper, element);
2116
+ wrapper.appendChild(element);
2117
+ return wrapper;
2118
+ },
2119
+
2120
+ inspect: function(element) {
2121
+ element = $(element);
2122
+ var result = '<' + element.tagName.toLowerCase();
2123
+ $H({'id': 'id', 'className': 'class'}).each(function(pair) {
2124
+ var property = pair.first(),
2125
+ attribute = pair.last(),
2126
+ value = (element[property] || '').toString();
2127
+ if (value) result += ' ' + attribute + '=' + value.inspect(true);
2128
+ });
2129
+ return result + '>';
2130
+ },
2131
+
2132
+ recursivelyCollect: function(element, property, maximumLength) {
2133
+ element = $(element);
2134
+ maximumLength = maximumLength || -1;
2135
+ var elements = [];
2136
+
2137
+ while (element = element[property]) {
2138
+ if (element.nodeType == 1)
2139
+ elements.push(Element.extend(element));
2140
+ if (elements.length == maximumLength)
2141
+ break;
2142
+ }
2143
+
2144
+ return elements;
2145
+ },
2146
+
2147
+ ancestors: function(element) {
2148
+ return Element.recursivelyCollect(element, 'parentNode');
2149
+ },
2150
+
2151
+ descendants: function(element) {
2152
+ return Element.select(element, "*");
2153
+ },
2154
+
2155
+ firstDescendant: function(element) {
2156
+ element = $(element).firstChild;
2157
+ while (element && element.nodeType != 1) element = element.nextSibling;
2158
+ return $(element);
2159
+ },
2160
+
2161
+ immediateDescendants: function(element) {
2162
+ var results = [], child = $(element).firstChild;
2163
+ while (child) {
2164
+ if (child.nodeType === 1) {
2165
+ results.push(Element.extend(child));
2166
+ }
2167
+ child = child.nextSibling;
2168
+ }
2169
+ return results;
2170
+ },
2171
+
2172
+ previousSiblings: function(element, maximumLength) {
2173
+ return Element.recursivelyCollect(element, 'previousSibling');
2174
+ },
2175
+
2176
+ nextSiblings: function(element) {
2177
+ return Element.recursivelyCollect(element, 'nextSibling');
2178
+ },
2179
+
2180
+ siblings: function(element) {
2181
+ element = $(element);
2182
+ return Element.previousSiblings(element).reverse()
2183
+ .concat(Element.nextSiblings(element));
2184
+ },
2185
+
2186
+ match: function(element, selector) {
2187
+ element = $(element);
2188
+ if (Object.isString(selector))
2189
+ return Prototype.Selector.match(element, selector);
2190
+ return selector.match(element);
2191
+ },
2192
+
2193
+ up: function(element, expression, index) {
2194
+ element = $(element);
2195
+ if (arguments.length == 1) return $(element.parentNode);
2196
+ var ancestors = Element.ancestors(element);
2197
+ return Object.isNumber(expression) ? ancestors[expression] :
2198
+ Prototype.Selector.find(ancestors, expression, index);
2199
+ },
2200
+
2201
+ down: function(element, expression, index) {
2202
+ element = $(element);
2203
+ if (arguments.length == 1) return Element.firstDescendant(element);
2204
+ return Object.isNumber(expression) ? Element.descendants(element)[expression] :
2205
+ Element.select(element, expression)[index || 0];
2206
+ },
2207
+
2208
+ previous: function(element, expression, index) {
2209
+ element = $(element);
2210
+ if (Object.isNumber(expression)) index = expression, expression = false;
2211
+ if (!Object.isNumber(index)) index = 0;
2212
+
2213
+ if (expression) {
2214
+ return Prototype.Selector.find(element.previousSiblings(), expression, index);
2215
+ } else {
2216
+ return element.recursivelyCollect("previousSibling", index + 1)[index];
2217
+ }
2218
+ },
2219
+
2220
+ next: function(element, expression, index) {
2221
+ element = $(element);
2222
+ if (Object.isNumber(expression)) index = expression, expression = false;
2223
+ if (!Object.isNumber(index)) index = 0;
2224
+
2225
+ if (expression) {
2226
+ return Prototype.Selector.find(element.nextSiblings(), expression, index);
2227
+ } else {
2228
+ var maximumLength = Object.isNumber(index) ? index + 1 : 1;
2229
+ return element.recursivelyCollect("nextSibling", index + 1)[index];
2230
+ }
2231
+ },
2232
+
2233
+
2234
+ select: function(element) {
2235
+ element = $(element);
2236
+ var expressions = Array.prototype.slice.call(arguments, 1).join(', ');
2237
+ return Prototype.Selector.select(expressions, element);
2238
+ },
2239
+
2240
+ adjacent: function(element) {
2241
+ element = $(element);
2242
+ var expressions = Array.prototype.slice.call(arguments, 1).join(', ');
2243
+ return Prototype.Selector.select(expressions, element.parentNode).without(element);
2244
+ },
2245
+
2246
+ identify: function(element) {
2247
+ element = $(element);
2248
+ var id = Element.readAttribute(element, 'id');
2249
+ if (id) return id;
2250
+ do { id = 'anonymous_element_' + Element.idCounter++ } while ($(id));
2251
+ Element.writeAttribute(element, 'id', id);
2252
+ return id;
2253
+ },
2254
+
2255
+ readAttribute: function(element, name) {
2256
+ element = $(element);
2257
+ if (Prototype.Browser.IE) {
2258
+ var t = Element._attributeTranslations.read;
2259
+ if (t.values[name]) return t.values[name](element, name);
2260
+ if (t.names[name]) name = t.names[name];
2261
+ if (name.include(':')) {
2262
+ return (!element.attributes || !element.attributes[name]) ? null :
2263
+ element.attributes[name].value;
2264
+ }
2265
+ }
2266
+ return element.getAttribute(name);
2267
+ },
2268
+
2269
+ writeAttribute: function(element, name, value) {
2270
+ element = $(element);
2271
+ var attributes = { }, t = Element._attributeTranslations.write;
2272
+
2273
+ if (typeof name == 'object') attributes = name;
2274
+ else attributes[name] = Object.isUndefined(value) ? true : value;
2275
+
2276
+ for (var attr in attributes) {
2277
+ name = t.names[attr] || attr;
2278
+ value = attributes[attr];
2279
+ if (t.values[attr]) name = t.values[attr](element, value);
2280
+ if (value === false || value === null)
2281
+ element.removeAttribute(name);
2282
+ else if (value === true)
2283
+ element.setAttribute(name, name);
2284
+ else element.setAttribute(name, value);
2285
+ }
2286
+ return element;
2287
+ },
2288
+
2289
+ getHeight: function(element) {
2290
+ return Element.getDimensions(element).height;
2291
+ },
2292
+
2293
+ getWidth: function(element) {
2294
+ return Element.getDimensions(element).width;
2295
+ },
2296
+
2297
+ classNames: function(element) {
2298
+ return new Element.ClassNames(element);
2299
+ },
2300
+
2301
+ hasClassName: function(element, className) {
2302
+ if (!(element = $(element))) return;
2303
+ var elementClassName = element.className;
2304
+ return (elementClassName.length > 0 && (elementClassName == className ||
2305
+ new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName)));
2306
+ },
2307
+
2308
+ addClassName: function(element, className) {
2309
+ if (!(element = $(element))) return;
2310
+ if (!Element.hasClassName(element, className))
2311
+ element.className += (element.className ? ' ' : '') + className;
2312
+ return element;
2313
+ },
2314
+
2315
+ removeClassName: function(element, className) {
2316
+ if (!(element = $(element))) return;
2317
+ element.className = element.className.replace(
2318
+ new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').strip();
2319
+ return element;
2320
+ },
2321
+
2322
+ toggleClassName: function(element, className) {
2323
+ if (!(element = $(element))) return;
2324
+ return Element[Element.hasClassName(element, className) ?
2325
+ 'removeClassName' : 'addClassName'](element, className);
2326
+ },
2327
+
2328
+ cleanWhitespace: function(element) {
2329
+ element = $(element);
2330
+ var node = element.firstChild;
2331
+ while (node) {
2332
+ var nextNode = node.nextSibling;
2333
+ if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
2334
+ element.removeChild(node);
2335
+ node = nextNode;
2336
+ }
2337
+ return element;
2338
+ },
2339
+
2340
+ empty: function(element) {
2341
+ return $(element).innerHTML.blank();
2342
+ },
2343
+
2344
+ descendantOf: function(element, ancestor) {
2345
+ element = $(element), ancestor = $(ancestor);
2346
+
2347
+ if (element.compareDocumentPosition)
2348
+ return (element.compareDocumentPosition(ancestor) & 8) === 8;
2349
+
2350
+ if (ancestor.contains)
2351
+ return ancestor.contains(element) && ancestor !== element;
2352
+
2353
+ while (element = element.parentNode)
2354
+ if (element == ancestor) return true;
2355
+
2356
+ return false;
2357
+ },
2358
+
2359
+ scrollTo: function(element) {
2360
+ element = $(element);
2361
+ var pos = Element.cumulativeOffset(element);
2362
+ window.scrollTo(pos[0], pos[1]);
2363
+ return element;
2364
+ },
2365
+
2366
+ getStyle: function(element, style) {
2367
+ element = $(element);
2368
+ style = style == 'float' ? 'cssFloat' : style.camelize();
2369
+ var value = element.style[style];
2370
+ if (!value || value == 'auto') {
2371
+ var css = document.defaultView.getComputedStyle(element, null);
2372
+ value = css ? css[style] : null;
2373
+ }
2374
+ if (style == 'opacity') return value ? parseFloat(value) : 1.0;
2375
+ return value == 'auto' ? null : value;
2376
+ },
2377
+
2378
+ getOpacity: function(element) {
2379
+ return $(element).getStyle('opacity');
2380
+ },
2381
+
2382
+ setStyle: function(element, styles) {
2383
+ element = $(element);
2384
+ var elementStyle = element.style, match;
2385
+ if (Object.isString(styles)) {
2386
+ element.style.cssText += ';' + styles;
2387
+ return styles.include('opacity') ?
2388
+ element.setOpacity(styles.match(/opacity:\s*(\d?\.?\d*)/)[1]) : element;
2389
+ }
2390
+ for (var property in styles)
2391
+ if (property == 'opacity') element.setOpacity(styles[property]);
2392
+ else
2393
+ elementStyle[(property == 'float' || property == 'cssFloat') ?
2394
+ (Object.isUndefined(elementStyle.styleFloat) ? 'cssFloat' : 'styleFloat') :
2395
+ property] = styles[property];
2396
+
2397
+ return element;
2398
+ },
2399
+
2400
+ setOpacity: function(element, value) {
2401
+ element = $(element);
2402
+ element.style.opacity = (value == 1 || value === '') ? '' :
2403
+ (value < 0.00001) ? 0 : value;
2404
+ return element;
2405
+ },
2406
+
2407
+ makePositioned: function(element) {
2408
+ element = $(element);
2409
+ var pos = Element.getStyle(element, 'position');
2410
+ if (pos == 'static' || !pos) {
2411
+ element._madePositioned = true;
2412
+ element.style.position = 'relative';
2413
+ if (Prototype.Browser.Opera) {
2414
+ element.style.top = 0;
2415
+ element.style.left = 0;
2416
+ }
2417
+ }
2418
+ return element;
2419
+ },
2420
+
2421
+ undoPositioned: function(element) {
2422
+ element = $(element);
2423
+ if (element._madePositioned) {
2424
+ element._madePositioned = undefined;
2425
+ element.style.position =
2426
+ element.style.top =
2427
+ element.style.left =
2428
+ element.style.bottom =
2429
+ element.style.right = '';
2430
+ }
2431
+ return element;
2432
+ },
2433
+
2434
+ makeClipping: function(element) {
2435
+ element = $(element);
2436
+ if (element._overflow) return element;
2437
+ element._overflow = Element.getStyle(element, 'overflow') || 'auto';
2438
+ if (element._overflow !== 'hidden')
2439
+ element.style.overflow = 'hidden';
2440
+ return element;
2441
+ },
2442
+
2443
+ undoClipping: function(element) {
2444
+ element = $(element);
2445
+ if (!element._overflow) return element;
2446
+ element.style.overflow = element._overflow == 'auto' ? '' : element._overflow;
2447
+ element._overflow = null;
2448
+ return element;
2449
+ },
2450
+
2451
+ clonePosition: function(element, source) {
2452
+ var options = Object.extend({
2453
+ setLeft: true,
2454
+ setTop: true,
2455
+ setWidth: true,
2456
+ setHeight: true,
2457
+ offsetTop: 0,
2458
+ offsetLeft: 0
2459
+ }, arguments[2] || { });
2460
+
2461
+ source = $(source);
2462
+ var p = Element.viewportOffset(source), delta = [0, 0], parent = null;
2463
+
2464
+ element = $(element);
2465
+
2466
+ if (Element.getStyle(element, 'position') == 'absolute') {
2467
+ parent = Element.getOffsetParent(element);
2468
+ delta = Element.viewportOffset(parent);
2469
+ }
2470
+
2471
+ if (parent == document.body) {
2472
+ delta[0] -= document.body.offsetLeft;
2473
+ delta[1] -= document.body.offsetTop;
2474
+ }
2475
+
2476
+ if (options.setLeft) element.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px';
2477
+ if (options.setTop) element.style.top = (p[1] - delta[1] + options.offsetTop) + 'px';
2478
+ if (options.setWidth) element.style.width = source.offsetWidth + 'px';
2479
+ if (options.setHeight) element.style.height = source.offsetHeight + 'px';
2480
+ return element;
2481
+ }
2482
+ };
2483
+
2484
+ Object.extend(Element.Methods, {
2485
+ getElementsBySelector: Element.Methods.select,
2486
+
2487
+ childElements: Element.Methods.immediateDescendants
2488
+ });
2489
+
2490
+ Element._attributeTranslations = {
2491
+ write: {
2492
+ names: {
2493
+ className: 'class',
2494
+ htmlFor: 'for'
2495
+ },
2496
+ values: { }
2497
+ }
2498
+ };
2499
+
2500
+ if (Prototype.Browser.Opera) {
2501
+ Element.Methods.getStyle = Element.Methods.getStyle.wrap(
2502
+ function(proceed, element, style) {
2503
+ switch (style) {
2504
+ case 'height': case 'width':
2505
+ if (!Element.visible(element)) return null;
2506
+
2507
+ var dim = parseInt(proceed(element, style), 10);
2508
+
2509
+ if (dim !== element['offset' + style.capitalize()])
2510
+ return dim + 'px';
2511
+
2512
+ var properties;
2513
+ if (style === 'height') {
2514
+ properties = ['border-top-width', 'padding-top',
2515
+ 'padding-bottom', 'border-bottom-width'];
2516
+ }
2517
+ else {
2518
+ properties = ['border-left-width', 'padding-left',
2519
+ 'padding-right', 'border-right-width'];
2520
+ }
2521
+ return properties.inject(dim, function(memo, property) {
2522
+ var val = proceed(element, property);
2523
+ return val === null ? memo : memo - parseInt(val, 10);
2524
+ }) + 'px';
2525
+ default: return proceed(element, style);
2526
+ }
2527
+ }
2528
+ );
2529
+
2530
+ Element.Methods.readAttribute = Element.Methods.readAttribute.wrap(
2531
+ function(proceed, element, attribute) {
2532
+ if (attribute === 'title') return element.title;
2533
+ return proceed(element, attribute);
2534
+ }
2535
+ );
2536
+ }
2537
+
2538
+ else if (Prototype.Browser.IE) {
2539
+ Element.Methods.getStyle = function(element, style) {
2540
+ element = $(element);
2541
+ style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize();
2542
+ var value = element.style[style];
2543
+ if (!value && element.currentStyle) value = element.currentStyle[style];
2544
+
2545
+ if (style == 'opacity') {
2546
+ if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
2547
+ if (value[1]) return parseFloat(value[1]) / 100;
2548
+ return 1.0;
2549
+ }
2550
+
2551
+ if (value == 'auto') {
2552
+ if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none'))
2553
+ return element['offset' + style.capitalize()] + 'px';
2554
+ return null;
2555
+ }
2556
+ return value;
2557
+ };
2558
+
2559
+ Element.Methods.setOpacity = function(element, value) {
2560
+ function stripAlpha(filter){
2561
+ return filter.replace(/alpha\([^\)]*\)/gi,'');
2562
+ }
2563
+ element = $(element);
2564
+ var currentStyle = element.currentStyle;
2565
+ if ((currentStyle && !currentStyle.hasLayout) ||
2566
+ (!currentStyle && element.style.zoom == 'normal'))
2567
+ element.style.zoom = 1;
2568
+
2569
+ var filter = element.getStyle('filter'), style = element.style;
2570
+ if (value == 1 || value === '') {
2571
+ (filter = stripAlpha(filter)) ?
2572
+ style.filter = filter : style.removeAttribute('filter');
2573
+ return element;
2574
+ } else if (value < 0.00001) value = 0;
2575
+ style.filter = stripAlpha(filter) +
2576
+ 'alpha(opacity=' + (value * 100) + ')';
2577
+ return element;
2578
+ };
2579
+
2580
+ Element._attributeTranslations = (function(){
2581
+
2582
+ var classProp = 'className',
2583
+ forProp = 'for',
2584
+ el = document.createElement('div');
2585
+
2586
+ el.setAttribute(classProp, 'x');
2587
+
2588
+ if (el.className !== 'x') {
2589
+ el.setAttribute('class', 'x');
2590
+ if (el.className === 'x') {
2591
+ classProp = 'class';
2592
+ }
2593
+ }
2594
+ el = null;
2595
+
2596
+ el = document.createElement('label');
2597
+ el.setAttribute(forProp, 'x');
2598
+ if (el.htmlFor !== 'x') {
2599
+ el.setAttribute('htmlFor', 'x');
2600
+ if (el.htmlFor === 'x') {
2601
+ forProp = 'htmlFor';
2602
+ }
2603
+ }
2604
+ el = null;
2605
+
2606
+ return {
2607
+ read: {
2608
+ names: {
2609
+ 'class': classProp,
2610
+ 'className': classProp,
2611
+ 'for': forProp,
2612
+ 'htmlFor': forProp
2613
+ },
2614
+ values: {
2615
+ _getAttr: function(element, attribute) {
2616
+ return element.getAttribute(attribute);
2617
+ },
2618
+ _getAttr2: function(element, attribute) {
2619
+ return element.getAttribute(attribute, 2);
2620
+ },
2621
+ _getAttrNode: function(element, attribute) {
2622
+ var node = element.getAttributeNode(attribute);
2623
+ return node ? node.value : "";
2624
+ },
2625
+ _getEv: (function(){
2626
+
2627
+ var el = document.createElement('div'), f;
2628
+ el.onclick = Prototype.emptyFunction;
2629
+ var value = el.getAttribute('onclick');
2630
+
2631
+ if (String(value).indexOf('{') > -1) {
2632
+ f = function(element, attribute) {
2633
+ attribute = element.getAttribute(attribute);
2634
+ if (!attribute) return null;
2635
+ attribute = attribute.toString();
2636
+ attribute = attribute.split('{')[1];
2637
+ attribute = attribute.split('}')[0];
2638
+ return attribute.strip();
2639
+ };
2640
+ }
2641
+ else if (value === '') {
2642
+ f = function(element, attribute) {
2643
+ attribute = element.getAttribute(attribute);
2644
+ if (!attribute) return null;
2645
+ return attribute.strip();
2646
+ };
2647
+ }
2648
+ el = null;
2649
+ return f;
2650
+ })(),
2651
+ _flag: function(element, attribute) {
2652
+ return $(element).hasAttribute(attribute) ? attribute : null;
2653
+ },
2654
+ style: function(element) {
2655
+ return element.style.cssText.toLowerCase();
2656
+ },
2657
+ title: function(element) {
2658
+ return element.title;
2659
+ }
2660
+ }
2661
+ }
2662
+ }
2663
+ })();
2664
+
2665
+ Element._attributeTranslations.write = {
2666
+ names: Object.extend({
2667
+ cellpadding: 'cellPadding',
2668
+ cellspacing: 'cellSpacing'
2669
+ }, Element._attributeTranslations.read.names),
2670
+ values: {
2671
+ checked: function(element, value) {
2672
+ element.checked = !!value;
2673
+ },
2674
+
2675
+ style: function(element, value) {
2676
+ element.style.cssText = value ? value : '';
2677
+ }
2678
+ }
2679
+ };
2680
+
2681
+ Element._attributeTranslations.has = {};
2682
+
2683
+ $w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' +
2684
+ 'encType maxLength readOnly longDesc frameBorder').each(function(attr) {
2685
+ Element._attributeTranslations.write.names[attr.toLowerCase()] = attr;
2686
+ Element._attributeTranslations.has[attr.toLowerCase()] = attr;
2687
+ });
2688
+
2689
+ (function(v) {
2690
+ Object.extend(v, {
2691
+ href: v._getAttr2,
2692
+ src: v._getAttr2,
2693
+ type: v._getAttr,
2694
+ action: v._getAttrNode,
2695
+ disabled: v._flag,
2696
+ checked: v._flag,
2697
+ readonly: v._flag,
2698
+ multiple: v._flag,
2699
+ onload: v._getEv,
2700
+ onunload: v._getEv,
2701
+ onclick: v._getEv,
2702
+ ondblclick: v._getEv,
2703
+ onmousedown: v._getEv,
2704
+ onmouseup: v._getEv,
2705
+ onmouseover: v._getEv,
2706
+ onmousemove: v._getEv,
2707
+ onmouseout: v._getEv,
2708
+ onfocus: v._getEv,
2709
+ onblur: v._getEv,
2710
+ onkeypress: v._getEv,
2711
+ onkeydown: v._getEv,
2712
+ onkeyup: v._getEv,
2713
+ onsubmit: v._getEv,
2714
+ onreset: v._getEv,
2715
+ onselect: v._getEv,
2716
+ onchange: v._getEv
2717
+ });
2718
+ })(Element._attributeTranslations.read.values);
2719
+
2720
+ if (Prototype.BrowserFeatures.ElementExtensions) {
2721
+ (function() {
2722
+ function _descendants(element) {
2723
+ var nodes = element.getElementsByTagName('*'), results = [];
2724
+ for (var i = 0, node; node = nodes[i]; i++)
2725
+ if (node.tagName !== "!") // Filter out comment nodes.
2726
+ results.push(node);
2727
+ return results;
2728
+ }
2729
+
2730
+ Element.Methods.down = function(element, expression, index) {
2731
+ element = $(element);
2732
+ if (arguments.length == 1) return element.firstDescendant();
2733
+ return Object.isNumber(expression) ? _descendants(element)[expression] :
2734
+ Element.select(element, expression)[index || 0];
2735
+ }
2736
+ })();
2737
+ }
2738
+
2739
+ }
2740
+
2741
+ else if (Prototype.Browser.Gecko && /rv:1\.8\.0/.test(navigator.userAgent)) {
2742
+ Element.Methods.setOpacity = function(element, value) {
2743
+ element = $(element);
2744
+ element.style.opacity = (value == 1) ? 0.999999 :
2745
+ (value === '') ? '' : (value < 0.00001) ? 0 : value;
2746
+ return element;
2747
+ };
2748
+ }
2749
+
2750
+ else if (Prototype.Browser.WebKit) {
2751
+ Element.Methods.setOpacity = function(element, value) {
2752
+ element = $(element);
2753
+ element.style.opacity = (value == 1 || value === '') ? '' :
2754
+ (value < 0.00001) ? 0 : value;
2755
+
2756
+ if (value == 1)
2757
+ if (element.tagName.toUpperCase() == 'IMG' && element.width) {
2758
+ element.width++; element.width--;
2759
+ } else try {
2760
+ var n = document.createTextNode(' ');
2761
+ element.appendChild(n);
2762
+ element.removeChild(n);
2763
+ } catch (e) { }
2764
+
2765
+ return element;
2766
+ };
2767
+ }
2768
+
2769
+ if ('outerHTML' in document.documentElement) {
2770
+ Element.Methods.replace = function(element, content) {
2771
+ element = $(element);
2772
+
2773
+ if (content && content.toElement) content = content.toElement();
2774
+ if (Object.isElement(content)) {
2775
+ element.parentNode.replaceChild(content, element);
2776
+ return element;
2777
+ }
2778
+
2779
+ content = Object.toHTML(content);
2780
+ var parent = element.parentNode, tagName = parent.tagName.toUpperCase();
2781
+
2782
+ if (Element._insertionTranslations.tags[tagName]) {
2783
+ var nextSibling = element.next(),
2784
+ fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
2785
+ parent.removeChild(element);
2786
+ if (nextSibling)
2787
+ fragments.each(function(node) { parent.insertBefore(node, nextSibling) });
2788
+ else
2789
+ fragments.each(function(node) { parent.appendChild(node) });
2790
+ }
2791
+ else element.outerHTML = content.stripScripts();
2792
+
2793
+ content.evalScripts.bind(content).defer();
2794
+ return element;
2795
+ };
2796
+ }
2797
+
2798
+ Element._returnOffset = function(l, t) {
2799
+ var result = [l, t];
2800
+ result.left = l;
2801
+ result.top = t;
2802
+ return result;
2803
+ };
2804
+
2805
+ Element._getContentFromAnonymousElement = function(tagName, html, force) {
2806
+ var div = new Element('div'),
2807
+ t = Element._insertionTranslations.tags[tagName];
2808
+
2809
+ var workaround = false;
2810
+ if (t) workaround = true;
2811
+ else if (force) {
2812
+ workaround = true;
2813
+ t = ['', '', 0];
2814
+ }
2815
+
2816
+ if (workaround) {
2817
+ div.innerHTML = '&nbsp;' + t[0] + html + t[1];
2818
+ div.removeChild(div.firstChild);
2819
+ for (var i = t[2]; i--; ) {
2820
+ div = div.firstChild;
2821
+ }
2822
+ }
2823
+ else {
2824
+ div.innerHTML = html;
2825
+ }
2826
+ return $A(div.childNodes);
2827
+ };
2828
+
2829
+ Element._insertionTranslations = {
2830
+ before: function(element, node) {
2831
+ element.parentNode.insertBefore(node, element);
2832
+ },
2833
+ top: function(element, node) {
2834
+ element.insertBefore(node, element.firstChild);
2835
+ },
2836
+ bottom: function(element, node) {
2837
+ element.appendChild(node);
2838
+ },
2839
+ after: function(element, node) {
2840
+ element.parentNode.insertBefore(node, element.nextSibling);
2841
+ },
2842
+ tags: {
2843
+ TABLE: ['<table>', '</table>', 1],
2844
+ TBODY: ['<table><tbody>', '</tbody></table>', 2],
2845
+ TR: ['<table><tbody><tr>', '</tr></tbody></table>', 3],
2846
+ TD: ['<table><tbody><tr><td>', '</td></tr></tbody></table>', 4],
2847
+ SELECT: ['<select>', '</select>', 1]
2848
+ }
2849
+ };
2850
+
2851
+ (function() {
2852
+ var tags = Element._insertionTranslations.tags;
2853
+ Object.extend(tags, {
2854
+ THEAD: tags.TBODY,
2855
+ TFOOT: tags.TBODY,
2856
+ TH: tags.TD
2857
+ });
2858
+ })();
2859
+
2860
+ Element.Methods.Simulated = {
2861
+ hasAttribute: function(element, attribute) {
2862
+ attribute = Element._attributeTranslations.has[attribute] || attribute;
2863
+ var node = $(element).getAttributeNode(attribute);
2864
+ return !!(node && node.specified);
2865
+ }
2866
+ };
2867
+
2868
+ Element.Methods.ByTag = { };
2869
+
2870
+ Object.extend(Element, Element.Methods);
2871
+
2872
+ (function(div) {
2873
+
2874
+ if (!Prototype.BrowserFeatures.ElementExtensions && div['__proto__']) {
2875
+ window.HTMLElement = { };
2876
+ window.HTMLElement.prototype = div['__proto__'];
2877
+ Prototype.BrowserFeatures.ElementExtensions = true;
2878
+ }
2879
+
2880
+ div = null;
2881
+
2882
+ })(document.createElement('div'));
2883
+
2884
+ Element.extend = (function() {
2885
+
2886
+ function checkDeficiency(tagName) {
2887
+ if (typeof window.Element != 'undefined') {
2888
+ var proto = window.Element.prototype;
2889
+ if (proto) {
2890
+ var id = '_' + (Math.random()+'').slice(2),
2891
+ el = document.createElement(tagName);
2892
+ proto[id] = 'x';
2893
+ var isBuggy = (el[id] !== 'x');
2894
+ delete proto[id];
2895
+ el = null;
2896
+ return isBuggy;
2897
+ }
2898
+ }
2899
+ return false;
2900
+ }
2901
+
2902
+ function extendElementWith(element, methods) {
2903
+ for (var property in methods) {
2904
+ var value = methods[property];
2905
+ if (Object.isFunction(value) && !(property in element))
2906
+ element[property] = value.methodize();
2907
+ }
2908
+ }
2909
+
2910
+ var HTMLOBJECTELEMENT_PROTOTYPE_BUGGY = checkDeficiency('object');
2911
+
2912
+ if (Prototype.BrowserFeatures.SpecificElementExtensions) {
2913
+ if (HTMLOBJECTELEMENT_PROTOTYPE_BUGGY) {
2914
+ return function(element) {
2915
+ if (element && typeof element._extendedByPrototype == 'undefined') {
2916
+ var t = element.tagName;
2917
+ if (t && (/^(?:object|applet|embed)$/i.test(t))) {
2918
+ extendElementWith(element, Element.Methods);
2919
+ extendElementWith(element, Element.Methods.Simulated);
2920
+ extendElementWith(element, Element.Methods.ByTag[t.toUpperCase()]);
2921
+ }
2922
+ }
2923
+ return element;
2924
+ }
2925
+ }
2926
+ return Prototype.K;
2927
+ }
2928
+
2929
+ var Methods = { }, ByTag = Element.Methods.ByTag;
2930
+
2931
+ var extend = Object.extend(function(element) {
2932
+ if (!element || typeof element._extendedByPrototype != 'undefined' ||
2933
+ element.nodeType != 1 || element == window) return element;
2934
+
2935
+ var methods = Object.clone(Methods),
2936
+ tagName = element.tagName.toUpperCase();
2937
+
2938
+ if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]);
2939
+
2940
+ extendElementWith(element, methods);
2941
+
2942
+ element._extendedByPrototype = Prototype.emptyFunction;
2943
+ return element;
2944
+
2945
+ }, {
2946
+ refresh: function() {
2947
+ if (!Prototype.BrowserFeatures.ElementExtensions) {
2948
+ Object.extend(Methods, Element.Methods);
2949
+ Object.extend(Methods, Element.Methods.Simulated);
2950
+ }
2951
+ }
2952
+ });
2953
+
2954
+ extend.refresh();
2955
+ return extend;
2956
+ })();
2957
+
2958
+ if (document.documentElement.hasAttribute) {
2959
+ Element.hasAttribute = function(element, attribute) {
2960
+ return element.hasAttribute(attribute);
2961
+ };
2962
+ }
2963
+ else {
2964
+ Element.hasAttribute = Element.Methods.Simulated.hasAttribute;
2965
+ }
2966
+
2967
+ Element.addMethods = function(methods) {
2968
+ var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag;
2969
+
2970
+ if (!methods) {
2971
+ Object.extend(Form, Form.Methods);
2972
+ Object.extend(Form.Element, Form.Element.Methods);
2973
+ Object.extend(Element.Methods.ByTag, {
2974
+ "FORM": Object.clone(Form.Methods),
2975
+ "INPUT": Object.clone(Form.Element.Methods),
2976
+ "SELECT": Object.clone(Form.Element.Methods),
2977
+ "TEXTAREA": Object.clone(Form.Element.Methods),
2978
+ "BUTTON": Object.clone(Form.Element.Methods)
2979
+ });
2980
+ }
2981
+
2982
+ if (arguments.length == 2) {
2983
+ var tagName = methods;
2984
+ methods = arguments[1];
2985
+ }
2986
+
2987
+ if (!tagName) Object.extend(Element.Methods, methods || { });
2988
+ else {
2989
+ if (Object.isArray(tagName)) tagName.each(extend);
2990
+ else extend(tagName);
2991
+ }
2992
+
2993
+ function extend(tagName) {
2994
+ tagName = tagName.toUpperCase();
2995
+ if (!Element.Methods.ByTag[tagName])
2996
+ Element.Methods.ByTag[tagName] = { };
2997
+ Object.extend(Element.Methods.ByTag[tagName], methods);
2998
+ }
2999
+
3000
+ function copy(methods, destination, onlyIfAbsent) {
3001
+ onlyIfAbsent = onlyIfAbsent || false;
3002
+ for (var property in methods) {
3003
+ var value = methods[property];
3004
+ if (!Object.isFunction(value)) continue;
3005
+ if (!onlyIfAbsent || !(property in destination))
3006
+ destination[property] = value.methodize();
3007
+ }
3008
+ }
3009
+
3010
+ function findDOMClass(tagName) {
3011
+ var klass;
3012
+ var trans = {
3013
+ "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph",
3014
+ "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList",
3015
+ "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading",
3016
+ "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote",
3017
+ "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION":
3018
+ "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD":
3019
+ "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR":
3020
+ "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET":
3021
+ "FrameSet", "IFRAME": "IFrame"
3022
+ };
3023
+ if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element';
3024
+ if (window[klass]) return window[klass];
3025
+ klass = 'HTML' + tagName + 'Element';
3026
+ if (window[klass]) return window[klass];
3027
+ klass = 'HTML' + tagName.capitalize() + 'Element';
3028
+ if (window[klass]) return window[klass];
3029
+
3030
+ var element = document.createElement(tagName),
3031
+ proto = element['__proto__'] || element.constructor.prototype;
3032
+
3033
+ element = null;
3034
+ return proto;
3035
+ }
3036
+
3037
+ var elementPrototype = window.HTMLElement ? HTMLElement.prototype :
3038
+ Element.prototype;
3039
+
3040
+ if (F.ElementExtensions) {
3041
+ copy(Element.Methods, elementPrototype);
3042
+ copy(Element.Methods.Simulated, elementPrototype, true);
3043
+ }
3044
+
3045
+ if (F.SpecificElementExtensions) {
3046
+ for (var tag in Element.Methods.ByTag) {
3047
+ var klass = findDOMClass(tag);
3048
+ if (Object.isUndefined(klass)) continue;
3049
+ copy(T[tag], klass.prototype);
3050
+ }
3051
+ }
3052
+
3053
+ Object.extend(Element, Element.Methods);
3054
+ delete Element.ByTag;
3055
+
3056
+ if (Element.extend.refresh) Element.extend.refresh();
3057
+ Element.cache = { };
3058
+ };
3059
+
3060
+
3061
+ document.viewport = {
3062
+
3063
+ getDimensions: function() {
3064
+ return { width: this.getWidth(), height: this.getHeight() };
3065
+ },
3066
+
3067
+ getScrollOffsets: function() {
3068
+ return Element._returnOffset(
3069
+ window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
3070
+ window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop);
3071
+ }
3072
+ };
3073
+
3074
+ (function(viewport) {
3075
+ var B = Prototype.Browser, doc = document, element, property = {};
3076
+
3077
+ function getRootElement() {
3078
+ if (B.WebKit && !doc.evaluate)
3079
+ return document;
3080
+
3081
+ if (B.Opera && window.parseFloat(window.opera.version()) < 9.5)
3082
+ return document.body;
3083
+
3084
+ return document.documentElement;
3085
+ }
3086
+
3087
+ function define(D) {
3088
+ if (!element) element = getRootElement();
3089
+
3090
+ property[D] = 'client' + D;
3091
+
3092
+ viewport['get' + D] = function() { return element[property[D]] };
3093
+ return viewport['get' + D]();
3094
+ }
3095
+
3096
+ viewport.getWidth = define.curry('Width');
3097
+
3098
+ viewport.getHeight = define.curry('Height');
3099
+ })(document.viewport);
3100
+
3101
+
3102
+ Element.Storage = {
3103
+ UID: 1
3104
+ };
3105
+
3106
+ Element.addMethods({
3107
+ getStorage: function(element) {
3108
+ if (!(element = $(element))) return;
3109
+
3110
+ var uid;
3111
+ if (element === window) {
3112
+ uid = 0;
3113
+ } else {
3114
+ if (typeof element._prototypeUID === "undefined")
3115
+ element._prototypeUID = Element.Storage.UID++;
3116
+ uid = element._prototypeUID;
3117
+ }
3118
+
3119
+ if (!Element.Storage[uid])
3120
+ Element.Storage[uid] = $H();
3121
+
3122
+ return Element.Storage[uid];
3123
+ },
3124
+
3125
+ store: function(element, key, value) {
3126
+ if (!(element = $(element))) return;
3127
+
3128
+ if (arguments.length === 2) {
3129
+ Element.getStorage(element).update(key);
3130
+ } else {
3131
+ Element.getStorage(element).set(key, value);
3132
+ }
3133
+
3134
+ return element;
3135
+ },
3136
+
3137
+ retrieve: function(element, key, defaultValue) {
3138
+ if (!(element = $(element))) return;
3139
+ var hash = Element.getStorage(element), value = hash.get(key);
3140
+
3141
+ if (Object.isUndefined(value)) {
3142
+ hash.set(key, defaultValue);
3143
+ value = defaultValue;
3144
+ }
3145
+
3146
+ return value;
3147
+ },
3148
+
3149
+ clone: function(element, deep) {
3150
+ if (!(element = $(element))) return;
3151
+ var clone = element.cloneNode(deep);
3152
+ clone._prototypeUID = void 0;
3153
+ if (deep) {
3154
+ var descendants = Element.select(clone, '*'),
3155
+ i = descendants.length;
3156
+ while (i--) {
3157
+ descendants[i]._prototypeUID = void 0;
3158
+ }
3159
+ }
3160
+ return Element.extend(clone);
3161
+ },
3162
+
3163
+ purge: function(element) {
3164
+ if (!(element = $(element))) return;
3165
+ var purgeElement = Element._purgeElement;
3166
+
3167
+ purgeElement(element);
3168
+
3169
+ var descendants = element.getElementsByTagName('*'),
3170
+ i = descendants.length;
3171
+
3172
+ while (i--) purgeElement(descendants[i]);
3173
+
3174
+ return null;
3175
+ }
3176
+ });
3177
+
3178
+ (function() {
3179
+
3180
+ function toDecimal(pctString) {
3181
+ var match = pctString.match(/^(\d+)%?$/i);
3182
+ if (!match) return null;
3183
+ return (Number(match[1]) / 100);
3184
+ }
3185
+
3186
+ function getPixelValue(value, property, context) {
3187
+ var element = null;
3188
+ if (Object.isElement(value)) {
3189
+ element = value;
3190
+ value = element.getStyle(property);
3191
+ }
3192
+
3193
+ if (value === null) {
3194
+ return null;
3195
+ }
3196
+
3197
+ if ((/^(?:-)?\d+(\.\d+)?(px)?$/i).test(value)) {
3198
+ return window.parseFloat(value);
3199
+ }
3200
+
3201
+ var isPercentage = value.include('%'), isViewport = (context === document.viewport);
3202
+
3203
+ if (/\d/.test(value) && element && element.runtimeStyle && !(isPercentage && isViewport)) {
3204
+ var style = element.style.left, rStyle = element.runtimeStyle.left;
3205
+ element.runtimeStyle.left = element.currentStyle.left;
3206
+ element.style.left = value || 0;
3207
+ value = element.style.pixelLeft;
3208
+ element.style.left = style;
3209
+ element.runtimeStyle.left = rStyle;
3210
+
3211
+ return value;
3212
+ }
3213
+
3214
+ if (element && isPercentage) {
3215
+ context = context || element.parentNode;
3216
+ var decimal = toDecimal(value);
3217
+ var whole = null;
3218
+ var position = element.getStyle('position');
3219
+
3220
+ var isHorizontal = property.include('left') || property.include('right') ||
3221
+ property.include('width');
3222
+
3223
+ var isVertical = property.include('top') || property.include('bottom') ||
3224
+ property.include('height');
3225
+
3226
+ if (context === document.viewport) {
3227
+ if (isHorizontal) {
3228
+ whole = document.viewport.getWidth();
3229
+ } else if (isVertical) {
3230
+ whole = document.viewport.getHeight();
3231
+ }
3232
+ } else {
3233
+ if (isHorizontal) {
3234
+ whole = $(context).measure('width');
3235
+ } else if (isVertical) {
3236
+ whole = $(context).measure('height');
3237
+ }
3238
+ }
3239
+
3240
+ return (whole === null) ? 0 : whole * decimal;
3241
+ }
3242
+
3243
+ return 0;
3244
+ }
3245
+
3246
+ function toCSSPixels(number) {
3247
+ if (Object.isString(number) && number.endsWith('px')) {
3248
+ return number;
3249
+ }
3250
+ return number + 'px';
3251
+ }
3252
+
3253
+ function isDisplayed(element) {
3254
+ var originalElement = element;
3255
+ while (element && element.parentNode) {
3256
+ var display = element.getStyle('display');
3257
+ if (display === 'none') {
3258
+ return false;
3259
+ }
3260
+ element = $(element.parentNode);
3261
+ }
3262
+ return true;
3263
+ }
3264
+
3265
+ var hasLayout = Prototype.K;
3266
+ if ('currentStyle' in document.documentElement) {
3267
+ hasLayout = function(element) {
3268
+ if (!element.currentStyle.hasLayout) {
3269
+ element.style.zoom = 1;
3270
+ }
3271
+ return element;
3272
+ };
3273
+ }
3274
+
3275
+ function cssNameFor(key) {
3276
+ if (key.include('border')) key = key + '-width';
3277
+ return key.camelize();
3278
+ }
3279
+
3280
+ Element.Layout = Class.create(Hash, {
3281
+ initialize: function($super, element, preCompute) {
3282
+ $super();
3283
+ this.element = $(element);
3284
+
3285
+ Element.Layout.PROPERTIES.each( function(property) {
3286
+ this._set(property, null);
3287
+ }, this);
3288
+
3289
+ if (preCompute) {
3290
+ this._preComputing = true;
3291
+ this._begin();
3292
+ Element.Layout.PROPERTIES.each( this._compute, this );
3293
+ this._end();
3294
+ this._preComputing = false;
3295
+ }
3296
+ },
3297
+
3298
+ _set: function(property, value) {
3299
+ return Hash.prototype.set.call(this, property, value);
3300
+ },
3301
+
3302
+ set: function(property, value) {
3303
+ throw "Properties of Element.Layout are read-only.";
3304
+ },
3305
+
3306
+ get: function($super, property) {
3307
+ var value = $super(property);
3308
+ return value === null ? this._compute(property) : value;
3309
+ },
3310
+
3311
+ _begin: function() {
3312
+ if (this._prepared) return;
3313
+
3314
+ var element = this.element;
3315
+ if (isDisplayed(element)) {
3316
+ this._prepared = true;
3317
+ return;
3318
+ }
3319
+
3320
+ var originalStyles = {
3321
+ position: element.style.position || '',
3322
+ width: element.style.width || '',
3323
+ visibility: element.style.visibility || '',
3324
+ display: element.style.display || ''
3325
+ };
3326
+
3327
+ element.store('prototype_original_styles', originalStyles);
3328
+
3329
+ var position = element.getStyle('position'),
3330
+ width = element.getStyle('width');
3331
+
3332
+ if (width === "0px" || width === null) {
3333
+ element.style.display = 'block';
3334
+ width = element.getStyle('width');
3335
+ }
3336
+
3337
+ var context = (position === 'fixed') ? document.viewport :
3338
+ element.parentNode;
3339
+
3340
+ element.setStyle({
3341
+ position: 'absolute',
3342
+ visibility: 'hidden',
3343
+ display: 'block'
3344
+ });
3345
+
3346
+ var positionedWidth = element.getStyle('width');
3347
+
3348
+ var newWidth;
3349
+ if (width && (positionedWidth === width)) {
3350
+ newWidth = getPixelValue(element, 'width', context);
3351
+ } else if (position === 'absolute' || position === 'fixed') {
3352
+ newWidth = getPixelValue(element, 'width', context);
3353
+ } else {
3354
+ var parent = element.parentNode, pLayout = $(parent).getLayout();
3355
+
3356
+ newWidth = pLayout.get('width') -
3357
+ this.get('margin-left') -
3358
+ this.get('border-left') -
3359
+ this.get('padding-left') -
3360
+ this.get('padding-right') -
3361
+ this.get('border-right') -
3362
+ this.get('margin-right');
3363
+ }
3364
+
3365
+ element.setStyle({ width: newWidth + 'px' });
3366
+
3367
+ this._prepared = true;
3368
+ },
3369
+
3370
+ _end: function() {
3371
+ var element = this.element;
3372
+ var originalStyles = element.retrieve('prototype_original_styles');
3373
+ element.store('prototype_original_styles', null);
3374
+ element.setStyle(originalStyles);
3375
+ this._prepared = false;
3376
+ },
3377
+
3378
+ _compute: function(property) {
3379
+ var COMPUTATIONS = Element.Layout.COMPUTATIONS;
3380
+ if (!(property in COMPUTATIONS)) {
3381
+ throw "Property not found.";
3382
+ }
3383
+
3384
+ return this._set(property, COMPUTATIONS[property].call(this, this.element));
3385
+ },
3386
+
3387
+ toObject: function() {
3388
+ var args = $A(arguments);
3389
+ var keys = (args.length === 0) ? Element.Layout.PROPERTIES :
3390
+ args.join(' ').split(' ');
3391
+ var obj = {};
3392
+ keys.each( function(key) {
3393
+ if (!Element.Layout.PROPERTIES.include(key)) return;
3394
+ var value = this.get(key);
3395
+ if (value != null) obj[key] = value;
3396
+ }, this);
3397
+ return obj;
3398
+ },
3399
+
3400
+ toHash: function() {
3401
+ var obj = this.toObject.apply(this, arguments);
3402
+ return new Hash(obj);
3403
+ },
3404
+
3405
+ toCSS: function() {
3406
+ var args = $A(arguments);
3407
+ var keys = (args.length === 0) ? Element.Layout.PROPERTIES :
3408
+ args.join(' ').split(' ');
3409
+ var css = {};
3410
+
3411
+ keys.each( function(key) {
3412
+ if (!Element.Layout.PROPERTIES.include(key)) return;
3413
+ if (Element.Layout.COMPOSITE_PROPERTIES.include(key)) return;
3414
+
3415
+ var value = this.get(key);
3416
+ if (value != null) css[cssNameFor(key)] = value + 'px';
3417
+ }, this);
3418
+ return css;
3419
+ },
3420
+
3421
+ inspect: function() {
3422
+ return "#<Element.Layout>";
3423
+ }
3424
+ });
3425
+
3426
+ Object.extend(Element.Layout, {
3427
+ PROPERTIES: $w('height width top left right bottom border-left border-right border-top border-bottom padding-left padding-right padding-top padding-bottom margin-top margin-bottom margin-left margin-right padding-box-width padding-box-height border-box-width border-box-height margin-box-width margin-box-height'),
3428
+
3429
+ COMPOSITE_PROPERTIES: $w('padding-box-width padding-box-height margin-box-width margin-box-height border-box-width border-box-height'),
3430
+
3431
+ COMPUTATIONS: {
3432
+ 'height': function(element) {
3433
+ if (!this._preComputing) this._begin();
3434
+
3435
+ var bHeight = this.get('border-box-height');
3436
+ if (bHeight <= 0) {
3437
+ if (!this._preComputing) this._end();
3438
+ return 0;
3439
+ }
3440
+
3441
+ var bTop = this.get('border-top'),
3442
+ bBottom = this.get('border-bottom');
3443
+
3444
+ var pTop = this.get('padding-top'),
3445
+ pBottom = this.get('padding-bottom');
3446
+
3447
+ if (!this._preComputing) this._end();
3448
+
3449
+ return bHeight - bTop - bBottom - pTop - pBottom;
3450
+ },
3451
+
3452
+ 'width': function(element) {
3453
+ if (!this._preComputing) this._begin();
3454
+
3455
+ var bWidth = this.get('border-box-width');
3456
+ if (bWidth <= 0) {
3457
+ if (!this._preComputing) this._end();
3458
+ return 0;
3459
+ }
3460
+
3461
+ var bLeft = this.get('border-left'),
3462
+ bRight = this.get('border-right');
3463
+
3464
+ var pLeft = this.get('padding-left'),
3465
+ pRight = this.get('padding-right');
3466
+
3467
+ if (!this._preComputing) this._end();
3468
+
3469
+ return bWidth - bLeft - bRight - pLeft - pRight;
3470
+ },
3471
+
3472
+ 'padding-box-height': function(element) {
3473
+ var height = this.get('height'),
3474
+ pTop = this.get('padding-top'),
3475
+ pBottom = this.get('padding-bottom');
3476
+
3477
+ return height + pTop + pBottom;
3478
+ },
3479
+
3480
+ 'padding-box-width': function(element) {
3481
+ var width = this.get('width'),
3482
+ pLeft = this.get('padding-left'),
3483
+ pRight = this.get('padding-right');
3484
+
3485
+ return width + pLeft + pRight;
3486
+ },
3487
+
3488
+ 'border-box-height': function(element) {
3489
+ if (!this._preComputing) this._begin();
3490
+ var height = element.offsetHeight;
3491
+ if (!this._preComputing) this._end();
3492
+ return height;
3493
+ },
3494
+
3495
+ 'border-box-width': function(element) {
3496
+ if (!this._preComputing) this._begin();
3497
+ var width = element.offsetWidth;
3498
+ if (!this._preComputing) this._end();
3499
+ return width;
3500
+ },
3501
+
3502
+ 'margin-box-height': function(element) {
3503
+ var bHeight = this.get('border-box-height'),
3504
+ mTop = this.get('margin-top'),
3505
+ mBottom = this.get('margin-bottom');
3506
+
3507
+ if (bHeight <= 0) return 0;
3508
+
3509
+ return bHeight + mTop + mBottom;
3510
+ },
3511
+
3512
+ 'margin-box-width': function(element) {
3513
+ var bWidth = this.get('border-box-width'),
3514
+ mLeft = this.get('margin-left'),
3515
+ mRight = this.get('margin-right');
3516
+
3517
+ if (bWidth <= 0) return 0;
3518
+
3519
+ return bWidth + mLeft + mRight;
3520
+ },
3521
+
3522
+ 'top': function(element) {
3523
+ var offset = element.positionedOffset();
3524
+ return offset.top;
3525
+ },
3526
+
3527
+ 'bottom': function(element) {
3528
+ var offset = element.positionedOffset(),
3529
+ parent = element.getOffsetParent(),
3530
+ pHeight = parent.measure('height');
3531
+
3532
+ var mHeight = this.get('border-box-height');
3533
+
3534
+ return pHeight - mHeight - offset.top;
3535
+ },
3536
+
3537
+ 'left': function(element) {
3538
+ var offset = element.positionedOffset();
3539
+ return offset.left;
3540
+ },
3541
+
3542
+ 'right': function(element) {
3543
+ var offset = element.positionedOffset(),
3544
+ parent = element.getOffsetParent(),
3545
+ pWidth = parent.measure('width');
3546
+
3547
+ var mWidth = this.get('border-box-width');
3548
+
3549
+ return pWidth - mWidth - offset.left;
3550
+ },
3551
+
3552
+ 'padding-top': function(element) {
3553
+ return getPixelValue(element, 'paddingTop');
3554
+ },
3555
+
3556
+ 'padding-bottom': function(element) {
3557
+ return getPixelValue(element, 'paddingBottom');
3558
+ },
3559
+
3560
+ 'padding-left': function(element) {
3561
+ return getPixelValue(element, 'paddingLeft');
3562
+ },
3563
+
3564
+ 'padding-right': function(element) {
3565
+ return getPixelValue(element, 'paddingRight');
3566
+ },
3567
+
3568
+ 'border-top': function(element) {
3569
+ return getPixelValue(element, 'borderTopWidth');
3570
+ },
3571
+
3572
+ 'border-bottom': function(element) {
3573
+ return getPixelValue(element, 'borderBottomWidth');
3574
+ },
3575
+
3576
+ 'border-left': function(element) {
3577
+ return getPixelValue(element, 'borderLeftWidth');
3578
+ },
3579
+
3580
+ 'border-right': function(element) {
3581
+ return getPixelValue(element, 'borderRightWidth');
3582
+ },
3583
+
3584
+ 'margin-top': function(element) {
3585
+ return getPixelValue(element, 'marginTop');
3586
+ },
3587
+
3588
+ 'margin-bottom': function(element) {
3589
+ return getPixelValue(element, 'marginBottom');
3590
+ },
3591
+
3592
+ 'margin-left': function(element) {
3593
+ return getPixelValue(element, 'marginLeft');
3594
+ },
3595
+
3596
+ 'margin-right': function(element) {
3597
+ return getPixelValue(element, 'marginRight');
3598
+ }
3599
+ }
3600
+ });
3601
+
3602
+ if ('getBoundingClientRect' in document.documentElement) {
3603
+ Object.extend(Element.Layout.COMPUTATIONS, {
3604
+ 'right': function(element) {
3605
+ var parent = hasLayout(element.getOffsetParent());
3606
+ var rect = element.getBoundingClientRect(),
3607
+ pRect = parent.getBoundingClientRect();
3608
+
3609
+ return (pRect.right - rect.right).round();
3610
+ },
3611
+
3612
+ 'bottom': function(element) {
3613
+ var parent = hasLayout(element.getOffsetParent());
3614
+ var rect = element.getBoundingClientRect(),
3615
+ pRect = parent.getBoundingClientRect();
3616
+
3617
+ return (pRect.bottom - rect.bottom).round();
3618
+ }
3619
+ });
3620
+ }
3621
+
3622
+ Element.Offset = Class.create({
3623
+ initialize: function(left, top) {
3624
+ this.left = left.round();
3625
+ this.top = top.round();
3626
+
3627
+ this[0] = this.left;
3628
+ this[1] = this.top;
3629
+ },
3630
+
3631
+ relativeTo: function(offset) {
3632
+ return new Element.Offset(
3633
+ this.left - offset.left,
3634
+ this.top - offset.top
3635
+ );
3636
+ },
3637
+
3638
+ inspect: function() {
3639
+ return "#<Element.Offset left: #{left} top: #{top}>".interpolate(this);
3640
+ },
3641
+
3642
+ toString: function() {
3643
+ return "[#{left}, #{top}]".interpolate(this);
3644
+ },
3645
+
3646
+ toArray: function() {
3647
+ return [this.left, this.top];
3648
+ }
3649
+ });
3650
+
3651
+ function getLayout(element, preCompute) {
3652
+ return new Element.Layout(element, preCompute);
3653
+ }
3654
+
3655
+ function measure(element, property) {
3656
+ return $(element).getLayout().get(property);
3657
+ }
3658
+
3659
+ function getDimensions(element) {
3660
+ element = $(element);
3661
+ var display = Element.getStyle(element, 'display');
3662
+
3663
+ if (display && display !== 'none') {
3664
+ return { width: element.offsetWidth, height: element.offsetHeight };
3665
+ }
3666
+
3667
+ var style = element.style;
3668
+ var originalStyles = {
3669
+ visibility: style.visibility,
3670
+ position: style.position,
3671
+ display: style.display
3672
+ };
3673
+
3674
+ var newStyles = {
3675
+ visibility: 'hidden',
3676
+ display: 'block'
3677
+ };
3678
+
3679
+ if (originalStyles.position !== 'fixed')
3680
+ newStyles.position = 'absolute';
3681
+
3682
+ Element.setStyle(element, newStyles);
3683
+
3684
+ var dimensions = {
3685
+ width: element.offsetWidth,
3686
+ height: element.offsetHeight
3687
+ };
3688
+
3689
+ Element.setStyle(element, originalStyles);
3690
+
3691
+ return dimensions;
3692
+ }
3693
+
3694
+ function getOffsetParent(element) {
3695
+ element = $(element);
3696
+
3697
+ if (isDocument(element) || isDetached(element) || isBody(element) || isHtml(element))
3698
+ return $(document.body);
3699
+
3700
+ var isInline = (Element.getStyle(element, 'display') === 'inline');
3701
+ if (!isInline && element.offsetParent) return $(element.offsetParent);
3702
+
3703
+ while ((element = element.parentNode) && element !== document.body) {
3704
+ if (Element.getStyle(element, 'position') !== 'static') {
3705
+ return isHtml(element) ? $(document.body) : $(element);
3706
+ }
3707
+ }
3708
+
3709
+ return $(document.body);
3710
+ }
3711
+
3712
+
3713
+ function cumulativeOffset(element) {
3714
+ element = $(element);
3715
+ var valueT = 0, valueL = 0;
3716
+ if (element.parentNode) {
3717
+ do {
3718
+ valueT += element.offsetTop || 0;
3719
+ valueL += element.offsetLeft || 0;
3720
+ element = element.offsetParent;
3721
+ } while (element);
3722
+ }
3723
+ return new Element.Offset(valueL, valueT);
3724
+ }
3725
+
3726
+ function positionedOffset(element) {
3727
+ element = $(element);
3728
+
3729
+ var layout = element.getLayout();
3730
+
3731
+ var valueT = 0, valueL = 0;
3732
+ do {
3733
+ valueT += element.offsetTop || 0;
3734
+ valueL += element.offsetLeft || 0;
3735
+ element = element.offsetParent;
3736
+ if (element) {
3737
+ if (isBody(element)) break;
3738
+ var p = Element.getStyle(element, 'position');
3739
+ if (p !== 'static') break;
3740
+ }
3741
+ } while (element);
3742
+
3743
+ valueL -= layout.get('margin-top');
3744
+ valueT -= layout.get('margin-left');
3745
+
3746
+ return new Element.Offset(valueL, valueT);
3747
+ }
3748
+
3749
+ function cumulativeScrollOffset(element) {
3750
+ var valueT = 0, valueL = 0;
3751
+ do {
3752
+ valueT += element.scrollTop || 0;
3753
+ valueL += element.scrollLeft || 0;
3754
+ element = element.parentNode;
3755
+ } while (element);
3756
+ return new Element.Offset(valueL, valueT);
3757
+ }
3758
+
3759
+ function viewportOffset(forElement) {
3760
+ element = $(element);
3761
+ var valueT = 0, valueL = 0, docBody = document.body;
3762
+
3763
+ var element = forElement;
3764
+ do {
3765
+ valueT += element.offsetTop || 0;
3766
+ valueL += element.offsetLeft || 0;
3767
+ if (element.offsetParent == docBody &&
3768
+ Element.getStyle(element, 'position') == 'absolute') break;
3769
+ } while (element = element.offsetParent);
3770
+
3771
+ element = forElement;
3772
+ do {
3773
+ if (element != docBody) {
3774
+ valueT -= element.scrollTop || 0;
3775
+ valueL -= element.scrollLeft || 0;
3776
+ }
3777
+ } while (element = element.parentNode);
3778
+ return new Element.Offset(valueL, valueT);
3779
+ }
3780
+
3781
+ function absolutize(element) {
3782
+ element = $(element);
3783
+
3784
+ if (Element.getStyle(element, 'position') === 'absolute') {
3785
+ return element;
3786
+ }
3787
+
3788
+ var offsetParent = getOffsetParent(element);
3789
+ var eOffset = element.viewportOffset(),
3790
+ pOffset = offsetParent.viewportOffset();
3791
+
3792
+ var offset = eOffset.relativeTo(pOffset);
3793
+ var layout = element.getLayout();
3794
+
3795
+ element.store('prototype_absolutize_original_styles', {
3796
+ left: element.getStyle('left'),
3797
+ top: element.getStyle('top'),
3798
+ width: element.getStyle('width'),
3799
+ height: element.getStyle('height')
3800
+ });
3801
+
3802
+ element.setStyle({
3803
+ position: 'absolute',
3804
+ top: offset.top + 'px',
3805
+ left: offset.left + 'px',
3806
+ width: layout.get('width') + 'px',
3807
+ height: layout.get('height') + 'px'
3808
+ });
3809
+
3810
+ return element;
3811
+ }
3812
+
3813
+ function relativize(element) {
3814
+ element = $(element);
3815
+ if (Element.getStyle(element, 'position') === 'relative') {
3816
+ return element;
3817
+ }
3818
+
3819
+ var originalStyles =
3820
+ element.retrieve('prototype_absolutize_original_styles');
3821
+
3822
+ if (originalStyles) element.setStyle(originalStyles);
3823
+ return element;
3824
+ }
3825
+
3826
+ if (Prototype.Browser.IE) {
3827
+ getOffsetParent = getOffsetParent.wrap(
3828
+ function(proceed, element) {
3829
+ element = $(element);
3830
+
3831
+ if (isDocument(element) || isDetached(element) || isBody(element) || isHtml(element))
3832
+ return $(document.body);
3833
+
3834
+ var position = element.getStyle('position');
3835
+ if (position !== 'static') return proceed(element);
3836
+
3837
+ element.setStyle({ position: 'relative' });
3838
+ var value = proceed(element);
3839
+ element.setStyle({ position: position });
3840
+ return value;
3841
+ }
3842
+ );
3843
+
3844
+ positionedOffset = positionedOffset.wrap(function(proceed, element) {
3845
+ element = $(element);
3846
+ if (!element.parentNode) return new Element.Offset(0, 0);
3847
+ var position = element.getStyle('position');
3848
+ if (position !== 'static') return proceed(element);
3849
+
3850
+ var offsetParent = element.getOffsetParent();
3851
+ if (offsetParent && offsetParent.getStyle('position') === 'fixed')
3852
+ hasLayout(offsetParent);
3853
+
3854
+ element.setStyle({ position: 'relative' });
3855
+ var value = proceed(element);
3856
+ element.setStyle({ position: position });
3857
+ return value;
3858
+ });
3859
+ } else if (Prototype.Browser.Webkit) {
3860
+ cumulativeOffset = function(element) {
3861
+ element = $(element);
3862
+ var valueT = 0, valueL = 0;
3863
+ do {
3864
+ valueT += element.offsetTop || 0;
3865
+ valueL += element.offsetLeft || 0;
3866
+ if (element.offsetParent == document.body)
3867
+ if (Element.getStyle(element, 'position') == 'absolute') break;
3868
+
3869
+ element = element.offsetParent;
3870
+ } while (element);
3871
+
3872
+ return new Element.Offset(valueL, valueT);
3873
+ };
3874
+ }
3875
+
3876
+
3877
+ Element.addMethods({
3878
+ getLayout: getLayout,
3879
+ measure: measure,
3880
+ getDimensions: getDimensions,
3881
+ getOffsetParent: getOffsetParent,
3882
+ cumulativeOffset: cumulativeOffset,
3883
+ positionedOffset: positionedOffset,
3884
+ cumulativeScrollOffset: cumulativeScrollOffset,
3885
+ viewportOffset: viewportOffset,
3886
+ absolutize: absolutize,
3887
+ relativize: relativize
3888
+ });
3889
+
3890
+ function isBody(element) {
3891
+ return element.nodeName.toUpperCase() === 'BODY';
3892
+ }
3893
+
3894
+ function isHtml(element) {
3895
+ return element.nodeName.toUpperCase() === 'HTML';
3896
+ }
3897
+
3898
+ function isDocument(element) {
3899
+ return element.nodeType === Node.DOCUMENT_NODE;
3900
+ }
3901
+
3902
+ function isDetached(element) {
3903
+ return element !== document.body &&
3904
+ !Element.descendantOf(element, document.body);
3905
+ }
3906
+
3907
+ if ('getBoundingClientRect' in document.documentElement) {
3908
+ Element.addMethods({
3909
+ viewportOffset: function(element) {
3910
+ element = $(element);
3911
+ if (isDetached(element)) return new Element.Offset(0, 0);
3912
+
3913
+ var rect = element.getBoundingClientRect(),
3914
+ docEl = document.documentElement;
3915
+ return new Element.Offset(rect.left - docEl.clientLeft,
3916
+ rect.top - docEl.clientTop);
3917
+ }
3918
+ });
3919
+ }
3920
+ })();
3921
+ window.$$ = function() {
3922
+ var expression = $A(arguments).join(', ');
3923
+ return Prototype.Selector.select(expression, document);
3924
+ };
3925
+
3926
+ Prototype.Selector = (function() {
3927
+
3928
+ function select() {
3929
+ throw new Error('Method "Prototype.Selector.select" must be defined.');
3930
+ }
3931
+
3932
+ function match() {
3933
+ throw new Error('Method "Prototype.Selector.match" must be defined.');
3934
+ }
3935
+
3936
+ function find(elements, expression, index) {
3937
+ index = index || 0;
3938
+ var match = Prototype.Selector.match, length = elements.length, matchIndex = 0, i;
3939
+
3940
+ for (i = 0; i < length; i++) {
3941
+ if (match(elements[i], expression) && index == matchIndex++) {
3942
+ return Element.extend(elements[i]);
3943
+ }
3944
+ }
3945
+ }
3946
+
3947
+ function extendElements(elements) {
3948
+ for (var i = 0, length = elements.length; i < length; i++) {
3949
+ Element.extend(elements[i]);
3950
+ }
3951
+ return elements;
3952
+ }
3953
+
3954
+
3955
+ var K = Prototype.K;
3956
+
3957
+ return {
3958
+ select: select,
3959
+ match: match,
3960
+ find: find,
3961
+ extendElements: (Element.extend === K) ? K : extendElements,
3962
+ extendElement: Element.extend
3963
+ };
3964
+ })();
3965
+ Prototype._original_property = window.Sizzle;
3966
+ /*!
3967
+ * Sizzle CSS Selector Engine - v1.0
3968
+ * Copyright 2009, The Dojo Foundation
3969
+ * Released under the MIT, BSD, and GPL Licenses.
3970
+ * More information: http://sizzlejs.com/
3971
+ */
3972
+ (function(){
3973
+
3974
+ var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
3975
+ done = 0,
3976
+ toString = Object.prototype.toString,
3977
+ hasDuplicate = false,
3978
+ baseHasDuplicate = true;
3979
+
3980
+ [0, 0].sort(function(){
3981
+ baseHasDuplicate = false;
3982
+ return 0;
3983
+ });
3984
+
3985
+ var Sizzle = function(selector, context, results, seed) {
3986
+ results = results || [];
3987
+ var origContext = context = context || document;
3988
+
3989
+ if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
3990
+ return [];
3991
+ }
3992
+
3993
+ if ( !selector || typeof selector !== "string" ) {
3994
+ return results;
3995
+ }
3996
+
3997
+ var parts = [], m, set, checkSet, check, mode, extra, prune = true, contextXML = isXML(context),
3998
+ soFar = selector;
3999
+
4000
+ while ( (chunker.exec(""), m = chunker.exec(soFar)) !== null ) {
4001
+ soFar = m[3];
4002
+
4003
+ parts.push( m[1] );
4004
+
4005
+ if ( m[2] ) {
4006
+ extra = m[3];
4007
+ break;
4008
+ }
4009
+ }
4010
+
4011
+ if ( parts.length > 1 && origPOS.exec( selector ) ) {
4012
+ if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
4013
+ set = posProcess( parts[0] + parts[1], context );
4014
+ } else {
4015
+ set = Expr.relative[ parts[0] ] ?
4016
+ [ context ] :
4017
+ Sizzle( parts.shift(), context );
4018
+
4019
+ while ( parts.length ) {
4020
+ selector = parts.shift();
4021
+
4022
+ if ( Expr.relative[ selector ] )
4023
+ selector += parts.shift();
4024
+
4025
+ set = posProcess( selector, set );
4026
+ }
4027
+ }
4028
+ } else {
4029
+ if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
4030
+ Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
4031
+ var ret = Sizzle.find( parts.shift(), context, contextXML );
4032
+ context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0];
4033
+ }
4034
+
4035
+ if ( context ) {
4036
+ var ret = seed ?
4037
+ { expr: parts.pop(), set: makeArray(seed) } :
4038
+ Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
4039
+ set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set;
4040
+
4041
+ if ( parts.length > 0 ) {
4042
+ checkSet = makeArray(set);
4043
+ } else {
4044
+ prune = false;
4045
+ }
4046
+
4047
+ while ( parts.length ) {
4048
+ var cur = parts.pop(), pop = cur;
4049
+
4050
+ if ( !Expr.relative[ cur ] ) {
4051
+ cur = "";
4052
+ } else {
4053
+ pop = parts.pop();
4054
+ }
4055
+
4056
+ if ( pop == null ) {
4057
+ pop = context;
4058
+ }
4059
+
4060
+ Expr.relative[ cur ]( checkSet, pop, contextXML );
4061
+ }
4062
+ } else {
4063
+ checkSet = parts = [];
4064
+ }
4065
+ }
4066
+
4067
+ if ( !checkSet ) {
4068
+ checkSet = set;
4069
+ }
4070
+
4071
+ if ( !checkSet ) {
4072
+ throw "Syntax error, unrecognized expression: " + (cur || selector);
4073
+ }
4074
+
4075
+ if ( toString.call(checkSet) === "[object Array]" ) {
4076
+ if ( !prune ) {
4077
+ results.push.apply( results, checkSet );
4078
+ } else if ( context && context.nodeType === 1 ) {
4079
+ for ( var i = 0; checkSet[i] != null; i++ ) {
4080
+ if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
4081
+ results.push( set[i] );
4082
+ }
4083
+ }
4084
+ } else {
4085
+ for ( var i = 0; checkSet[i] != null; i++ ) {
4086
+ if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
4087
+ results.push( set[i] );
4088
+ }
4089
+ }
4090
+ }
4091
+ } else {
4092
+ makeArray( checkSet, results );
4093
+ }
4094
+
4095
+ if ( extra ) {
4096
+ Sizzle( extra, origContext, results, seed );
4097
+ Sizzle.uniqueSort( results );
4098
+ }
4099
+
4100
+ return results;
4101
+ };
4102
+
4103
+ Sizzle.uniqueSort = function(results){
4104
+ if ( sortOrder ) {
4105
+ hasDuplicate = baseHasDuplicate;
4106
+ results.sort(sortOrder);
4107
+
4108
+ if ( hasDuplicate ) {
4109
+ for ( var i = 1; i < results.length; i++ ) {
4110
+ if ( results[i] === results[i-1] ) {
4111
+ results.splice(i--, 1);
4112
+ }
4113
+ }
4114
+ }
4115
+ }
4116
+
4117
+ return results;
4118
+ };
4119
+
4120
+ Sizzle.matches = function(expr, set){
4121
+ return Sizzle(expr, null, null, set);
4122
+ };
4123
+
4124
+ Sizzle.find = function(expr, context, isXML){
4125
+ var set, match;
4126
+
4127
+ if ( !expr ) {
4128
+ return [];
4129
+ }
4130
+
4131
+ for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
4132
+ var type = Expr.order[i], match;
4133
+
4134
+ if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
4135
+ var left = match[1];
4136
+ match.splice(1,1);
4137
+
4138
+ if ( left.substr( left.length - 1 ) !== "\\" ) {
4139
+ match[1] = (match[1] || "").replace(/\\/g, "");
4140
+ set = Expr.find[ type ]( match, context, isXML );
4141
+ if ( set != null ) {
4142
+ expr = expr.replace( Expr.match[ type ], "" );
4143
+ break;
4144
+ }
4145
+ }
4146
+ }
4147
+ }
4148
+
4149
+ if ( !set ) {
4150
+ set = context.getElementsByTagName("*");
4151
+ }
4152
+
4153
+ return {set: set, expr: expr};
4154
+ };
4155
+
4156
+ Sizzle.filter = function(expr, set, inplace, not){
4157
+ var old = expr, result = [], curLoop = set, match, anyFound,
4158
+ isXMLFilter = set && set[0] && isXML(set[0]);
4159
+
4160
+ while ( expr && set.length ) {
4161
+ for ( var type in Expr.filter ) {
4162
+ if ( (match = Expr.match[ type ].exec( expr )) != null ) {
4163
+ var filter = Expr.filter[ type ], found, item;
4164
+ anyFound = false;
4165
+
4166
+ if ( curLoop == result ) {
4167
+ result = [];
4168
+ }
4169
+
4170
+ if ( Expr.preFilter[ type ] ) {
4171
+ match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
4172
+
4173
+ if ( !match ) {
4174
+ anyFound = found = true;
4175
+ } else if ( match === true ) {
4176
+ continue;
4177
+ }
4178
+ }
4179
+
4180
+ if ( match ) {
4181
+ for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
4182
+ if ( item ) {
4183
+ found = filter( item, match, i, curLoop );
4184
+ var pass = not ^ !!found;
4185
+
4186
+ if ( inplace && found != null ) {
4187
+ if ( pass ) {
4188
+ anyFound = true;
4189
+ } else {
4190
+ curLoop[i] = false;
4191
+ }
4192
+ } else if ( pass ) {
4193
+ result.push( item );
4194
+ anyFound = true;
4195
+ }
4196
+ }
4197
+ }
4198
+ }
4199
+
4200
+ if ( found !== undefined ) {
4201
+ if ( !inplace ) {
4202
+ curLoop = result;
4203
+ }
4204
+
4205
+ expr = expr.replace( Expr.match[ type ], "" );
4206
+
4207
+ if ( !anyFound ) {
4208
+ return [];
4209
+ }
4210
+
4211
+ break;
4212
+ }
4213
+ }
4214
+ }
4215
+
4216
+ if ( expr == old ) {
4217
+ if ( anyFound == null ) {
4218
+ throw "Syntax error, unrecognized expression: " + expr;
4219
+ } else {
4220
+ break;
4221
+ }
4222
+ }
4223
+
4224
+ old = expr;
4225
+ }
4226
+
4227
+ return curLoop;
4228
+ };
4229
+
4230
+ var Expr = Sizzle.selectors = {
4231
+ order: [ "ID", "NAME", "TAG" ],
4232
+ match: {
4233
+ ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
4234
+ CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
4235
+ NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,
4236
+ ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
4237
+ TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,
4238
+ CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
4239
+ POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
4240
+ PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/
4241
+ },
4242
+ leftMatch: {},
4243
+ attrMap: {
4244
+ "class": "className",
4245
+ "for": "htmlFor"
4246
+ },
4247
+ attrHandle: {
4248
+ href: function(elem){
4249
+ return elem.getAttribute("href");
4250
+ }
4251
+ },
4252
+ relative: {
4253
+ "+": function(checkSet, part, isXML){
4254
+ var isPartStr = typeof part === "string",
4255
+ isTag = isPartStr && !/\W/.test(part),
4256
+ isPartStrNotTag = isPartStr && !isTag;
4257
+
4258
+ if ( isTag && !isXML ) {
4259
+ part = part.toUpperCase();
4260
+ }
4261
+
4262
+ for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
4263
+ if ( (elem = checkSet[i]) ) {
4264
+ while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
4265
+
4266
+ checkSet[i] = isPartStrNotTag || elem && elem.nodeName === part ?
4267
+ elem || false :
4268
+ elem === part;
4269
+ }
4270
+ }
4271
+
4272
+ if ( isPartStrNotTag ) {
4273
+ Sizzle.filter( part, checkSet, true );
4274
+ }
4275
+ },
4276
+ ">": function(checkSet, part, isXML){
4277
+ var isPartStr = typeof part === "string";
4278
+
4279
+ if ( isPartStr && !/\W/.test(part) ) {
4280
+ part = isXML ? part : part.toUpperCase();
4281
+
4282
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
4283
+ var elem = checkSet[i];
4284
+ if ( elem ) {
4285
+ var parent = elem.parentNode;
4286
+ checkSet[i] = parent.nodeName === part ? parent : false;
4287
+ }
4288
+ }
4289
+ } else {
4290
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
4291
+ var elem = checkSet[i];
4292
+ if ( elem ) {
4293
+ checkSet[i] = isPartStr ?
4294
+ elem.parentNode :
4295
+ elem.parentNode === part;
4296
+ }
4297
+ }
4298
+
4299
+ if ( isPartStr ) {
4300
+ Sizzle.filter( part, checkSet, true );
4301
+ }
4302
+ }
4303
+ },
4304
+ "": function(checkSet, part, isXML){
4305
+ var doneName = done++, checkFn = dirCheck;
4306
+
4307
+ if ( !/\W/.test(part) ) {
4308
+ var nodeCheck = part = isXML ? part : part.toUpperCase();
4309
+ checkFn = dirNodeCheck;
4310
+ }
4311
+
4312
+ checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
4313
+ },
4314
+ "~": function(checkSet, part, isXML){
4315
+ var doneName = done++, checkFn = dirCheck;
4316
+
4317
+ if ( typeof part === "string" && !/\W/.test(part) ) {
4318
+ var nodeCheck = part = isXML ? part : part.toUpperCase();
4319
+ checkFn = dirNodeCheck;
4320
+ }
4321
+
4322
+ checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
4323
+ }
4324
+ },
4325
+ find: {
4326
+ ID: function(match, context, isXML){
4327
+ if ( typeof context.getElementById !== "undefined" && !isXML ) {
4328
+ var m = context.getElementById(match[1]);
4329
+ return m ? [m] : [];
4330
+ }
4331
+ },
4332
+ NAME: function(match, context, isXML){
4333
+ if ( typeof context.getElementsByName !== "undefined" ) {
4334
+ var ret = [], results = context.getElementsByName(match[1]);
4335
+
4336
+ for ( var i = 0, l = results.length; i < l; i++ ) {
4337
+ if ( results[i].getAttribute("name") === match[1] ) {
4338
+ ret.push( results[i] );
4339
+ }
4340
+ }
4341
+
4342
+ return ret.length === 0 ? null : ret;
4343
+ }
4344
+ },
4345
+ TAG: function(match, context){
4346
+ return context.getElementsByTagName(match[1]);
4347
+ }
4348
+ },
4349
+ preFilter: {
4350
+ CLASS: function(match, curLoop, inplace, result, not, isXML){
4351
+ match = " " + match[1].replace(/\\/g, "") + " ";
4352
+
4353
+ if ( isXML ) {
4354
+ return match;
4355
+ }
4356
+
4357
+ for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
4358
+ if ( elem ) {
4359
+ if ( not ^ (elem.className && (" " + elem.className + " ").indexOf(match) >= 0) ) {
4360
+ if ( !inplace )
4361
+ result.push( elem );
4362
+ } else if ( inplace ) {
4363
+ curLoop[i] = false;
4364
+ }
4365
+ }
4366
+ }
4367
+
4368
+ return false;
4369
+ },
4370
+ ID: function(match){
4371
+ return match[1].replace(/\\/g, "");
4372
+ },
4373
+ TAG: function(match, curLoop){
4374
+ for ( var i = 0; curLoop[i] === false; i++ ){}
4375
+ return curLoop[i] && isXML(curLoop[i]) ? match[1] : match[1].toUpperCase();
4376
+ },
4377
+ CHILD: function(match){
4378
+ if ( match[1] == "nth" ) {
4379
+ var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
4380
+ match[2] == "even" && "2n" || match[2] == "odd" && "2n+1" ||
4381
+ !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
4382
+
4383
+ match[2] = (test[1] + (test[2] || 1)) - 0;
4384
+ match[3] = test[3] - 0;
4385
+ }
4386
+
4387
+ match[0] = done++;
4388
+
4389
+ return match;
4390
+ },
4391
+ ATTR: function(match, curLoop, inplace, result, not, isXML){
4392
+ var name = match[1].replace(/\\/g, "");
4393
+
4394
+ if ( !isXML && Expr.attrMap[name] ) {
4395
+ match[1] = Expr.attrMap[name];
4396
+ }
4397
+
4398
+ if ( match[2] === "~=" ) {
4399
+ match[4] = " " + match[4] + " ";
4400
+ }
4401
+
4402
+ return match;
4403
+ },
4404
+ PSEUDO: function(match, curLoop, inplace, result, not){
4405
+ if ( match[1] === "not" ) {
4406
+ if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
4407
+ match[3] = Sizzle(match[3], null, null, curLoop);
4408
+ } else {
4409
+ var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
4410
+ if ( !inplace ) {
4411
+ result.push.apply( result, ret );
4412
+ }
4413
+ return false;
4414
+ }
4415
+ } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
4416
+ return true;
4417
+ }
4418
+
4419
+ return match;
4420
+ },
4421
+ POS: function(match){
4422
+ match.unshift( true );
4423
+ return match;
4424
+ }
4425
+ },
4426
+ filters: {
4427
+ enabled: function(elem){
4428
+ return elem.disabled === false && elem.type !== "hidden";
4429
+ },
4430
+ disabled: function(elem){
4431
+ return elem.disabled === true;
4432
+ },
4433
+ checked: function(elem){
4434
+ return elem.checked === true;
4435
+ },
4436
+ selected: function(elem){
4437
+ elem.parentNode.selectedIndex;
4438
+ return elem.selected === true;
4439
+ },
4440
+ parent: function(elem){
4441
+ return !!elem.firstChild;
4442
+ },
4443
+ empty: function(elem){
4444
+ return !elem.firstChild;
4445
+ },
4446
+ has: function(elem, i, match){
4447
+ return !!Sizzle( match[3], elem ).length;
4448
+ },
4449
+ header: function(elem){
4450
+ return /h\d/i.test( elem.nodeName );
4451
+ },
4452
+ text: function(elem){
4453
+ return "text" === elem.type;
4454
+ },
4455
+ radio: function(elem){
4456
+ return "radio" === elem.type;
4457
+ },
4458
+ checkbox: function(elem){
4459
+ return "checkbox" === elem.type;
4460
+ },
4461
+ file: function(elem){
4462
+ return "file" === elem.type;
4463
+ },
4464
+ password: function(elem){
4465
+ return "password" === elem.type;
4466
+ },
4467
+ submit: function(elem){
4468
+ return "submit" === elem.type;
4469
+ },
4470
+ image: function(elem){
4471
+ return "image" === elem.type;
4472
+ },
4473
+ reset: function(elem){
4474
+ return "reset" === elem.type;
4475
+ },
4476
+ button: function(elem){
4477
+ return "button" === elem.type || elem.nodeName.toUpperCase() === "BUTTON";
4478
+ },
4479
+ input: function(elem){
4480
+ return /input|select|textarea|button/i.test(elem.nodeName);
4481
+ }
4482
+ },
4483
+ setFilters: {
4484
+ first: function(elem, i){
4485
+ return i === 0;
4486
+ },
4487
+ last: function(elem, i, match, array){
4488
+ return i === array.length - 1;
4489
+ },
4490
+ even: function(elem, i){
4491
+ return i % 2 === 0;
4492
+ },
4493
+ odd: function(elem, i){
4494
+ return i % 2 === 1;
4495
+ },
4496
+ lt: function(elem, i, match){
4497
+ return i < match[3] - 0;
4498
+ },
4499
+ gt: function(elem, i, match){
4500
+ return i > match[3] - 0;
4501
+ },
4502
+ nth: function(elem, i, match){
4503
+ return match[3] - 0 == i;
4504
+ },
4505
+ eq: function(elem, i, match){
4506
+ return match[3] - 0 == i;
4507
+ }
4508
+ },
4509
+ filter: {
4510
+ PSEUDO: function(elem, match, i, array){
4511
+ var name = match[1], filter = Expr.filters[ name ];
4512
+
4513
+ if ( filter ) {
4514
+ return filter( elem, i, match, array );
4515
+ } else if ( name === "contains" ) {
4516
+ return (elem.textContent || elem.innerText || "").indexOf(match[3]) >= 0;
4517
+ } else if ( name === "not" ) {
4518
+ var not = match[3];
4519
+
4520
+ for ( var i = 0, l = not.length; i < l; i++ ) {
4521
+ if ( not[i] === elem ) {
4522
+ return false;
4523
+ }
4524
+ }
4525
+
4526
+ return true;
4527
+ }
4528
+ },
4529
+ CHILD: function(elem, match){
4530
+ var type = match[1], node = elem;
4531
+ switch (type) {
4532
+ case 'only':
4533
+ case 'first':
4534
+ while ( (node = node.previousSibling) ) {
4535
+ if ( node.nodeType === 1 ) return false;
4536
+ }
4537
+ if ( type == 'first') return true;
4538
+ node = elem;
4539
+ case 'last':
4540
+ while ( (node = node.nextSibling) ) {
4541
+ if ( node.nodeType === 1 ) return false;
4542
+ }
4543
+ return true;
4544
+ case 'nth':
4545
+ var first = match[2], last = match[3];
4546
+
4547
+ if ( first == 1 && last == 0 ) {
4548
+ return true;
4549
+ }
4550
+
4551
+ var doneName = match[0],
4552
+ parent = elem.parentNode;
4553
+
4554
+ if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
4555
+ var count = 0;
4556
+ for ( node = parent.firstChild; node; node = node.nextSibling ) {
4557
+ if ( node.nodeType === 1 ) {
4558
+ node.nodeIndex = ++count;
4559
+ }
4560
+ }
4561
+ parent.sizcache = doneName;
4562
+ }
4563
+
4564
+ var diff = elem.nodeIndex - last;
4565
+ if ( first == 0 ) {
4566
+ return diff == 0;
4567
+ } else {
4568
+ return ( diff % first == 0 && diff / first >= 0 );
4569
+ }
4570
+ }
4571
+ },
4572
+ ID: function(elem, match){
4573
+ return elem.nodeType === 1 && elem.getAttribute("id") === match;
4574
+ },
4575
+ TAG: function(elem, match){
4576
+ return (match === "*" && elem.nodeType === 1) || elem.nodeName === match;
4577
+ },
4578
+ CLASS: function(elem, match){
4579
+ return (" " + (elem.className || elem.getAttribute("class")) + " ")
4580
+ .indexOf( match ) > -1;
4581
+ },
4582
+ ATTR: function(elem, match){
4583
+ var name = match[1],
4584
+ result = Expr.attrHandle[ name ] ?
4585
+ Expr.attrHandle[ name ]( elem ) :
4586
+ elem[ name ] != null ?
4587
+ elem[ name ] :
4588
+ elem.getAttribute( name ),
4589
+ value = result + "",
4590
+ type = match[2],
4591
+ check = match[4];
4592
+
4593
+ return result == null ?
4594
+ type === "!=" :
4595
+ type === "=" ?
4596
+ value === check :
4597
+ type === "*=" ?
4598
+ value.indexOf(check) >= 0 :
4599
+ type === "~=" ?
4600
+ (" " + value + " ").indexOf(check) >= 0 :
4601
+ !check ?
4602
+ value && result !== false :
4603
+ type === "!=" ?
4604
+ value != check :
4605
+ type === "^=" ?
4606
+ value.indexOf(check) === 0 :
4607
+ type === "$=" ?
4608
+ value.substr(value.length - check.length) === check :
4609
+ type === "|=" ?
4610
+ value === check || value.substr(0, check.length + 1) === check + "-" :
4611
+ false;
4612
+ },
4613
+ POS: function(elem, match, i, array){
4614
+ var name = match[2], filter = Expr.setFilters[ name ];
4615
+
4616
+ if ( filter ) {
4617
+ return filter( elem, i, match, array );
4618
+ }
4619
+ }
4620
+ }
4621
+ };
4622
+
4623
+ var origPOS = Expr.match.POS;
4624
+
4625
+ for ( var type in Expr.match ) {
4626
+ Expr.match[ type ] = new RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
4627
+ Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source );
4628
+ }
4629
+
4630
+ var makeArray = function(array, results) {
4631
+ array = Array.prototype.slice.call( array, 0 );
4632
+
4633
+ if ( results ) {
4634
+ results.push.apply( results, array );
4635
+ return results;
4636
+ }
4637
+
4638
+ return array;
4639
+ };
4640
+
4641
+ try {
4642
+ Array.prototype.slice.call( document.documentElement.childNodes, 0 );
4643
+
4644
+ } catch(e){
4645
+ makeArray = function(array, results) {
4646
+ var ret = results || [];
4647
+
4648
+ if ( toString.call(array) === "[object Array]" ) {
4649
+ Array.prototype.push.apply( ret, array );
4650
+ } else {
4651
+ if ( typeof array.length === "number" ) {
4652
+ for ( var i = 0, l = array.length; i < l; i++ ) {
4653
+ ret.push( array[i] );
4654
+ }
4655
+ } else {
4656
+ for ( var i = 0; array[i]; i++ ) {
4657
+ ret.push( array[i] );
4658
+ }
4659
+ }
4660
+ }
4661
+
4662
+ return ret;
4663
+ };
4664
+ }
4665
+
4666
+ var sortOrder;
4667
+
4668
+ if ( document.documentElement.compareDocumentPosition ) {
4669
+ sortOrder = function( a, b ) {
4670
+ if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
4671
+ if ( a == b ) {
4672
+ hasDuplicate = true;
4673
+ }
4674
+ return 0;
4675
+ }
4676
+
4677
+ var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
4678
+ if ( ret === 0 ) {
4679
+ hasDuplicate = true;
4680
+ }
4681
+ return ret;
4682
+ };
4683
+ } else if ( "sourceIndex" in document.documentElement ) {
4684
+ sortOrder = function( a, b ) {
4685
+ if ( !a.sourceIndex || !b.sourceIndex ) {
4686
+ if ( a == b ) {
4687
+ hasDuplicate = true;
4688
+ }
4689
+ return 0;
4690
+ }
4691
+
4692
+ var ret = a.sourceIndex - b.sourceIndex;
4693
+ if ( ret === 0 ) {
4694
+ hasDuplicate = true;
4695
+ }
4696
+ return ret;
4697
+ };
4698
+ } else if ( document.createRange ) {
4699
+ sortOrder = function( a, b ) {
4700
+ if ( !a.ownerDocument || !b.ownerDocument ) {
4701
+ if ( a == b ) {
4702
+ hasDuplicate = true;
4703
+ }
4704
+ return 0;
4705
+ }
4706
+
4707
+ var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
4708
+ aRange.setStart(a, 0);
4709
+ aRange.setEnd(a, 0);
4710
+ bRange.setStart(b, 0);
4711
+ bRange.setEnd(b, 0);
4712
+ var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
4713
+ if ( ret === 0 ) {
4714
+ hasDuplicate = true;
4715
+ }
4716
+ return ret;
4717
+ };
4718
+ }
4719
+
4720
+ (function(){
4721
+ var form = document.createElement("div"),
4722
+ id = "script" + (new Date).getTime();
4723
+ form.innerHTML = "<a name='" + id + "'/>";
4724
+
4725
+ var root = document.documentElement;
4726
+ root.insertBefore( form, root.firstChild );
4727
+
4728
+ if ( !!document.getElementById( id ) ) {
4729
+ Expr.find.ID = function(match, context, isXML){
4730
+ if ( typeof context.getElementById !== "undefined" && !isXML ) {
4731
+ var m = context.getElementById(match[1]);
4732
+ return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
4733
+ }
4734
+ };
4735
+
4736
+ Expr.filter.ID = function(elem, match){
4737
+ var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
4738
+ return elem.nodeType === 1 && node && node.nodeValue === match;
4739
+ };
4740
+ }
4741
+
4742
+ root.removeChild( form );
4743
+ root = form = null; // release memory in IE
4744
+ })();
4745
+
4746
+ (function(){
4747
+
4748
+ var div = document.createElement("div");
4749
+ div.appendChild( document.createComment("") );
4750
+
4751
+ if ( div.getElementsByTagName("*").length > 0 ) {
4752
+ Expr.find.TAG = function(match, context){
4753
+ var results = context.getElementsByTagName(match[1]);
4754
+
4755
+ if ( match[1] === "*" ) {
4756
+ var tmp = [];
4757
+
4758
+ for ( var i = 0; results[i]; i++ ) {
4759
+ if ( results[i].nodeType === 1 ) {
4760
+ tmp.push( results[i] );
4761
+ }
4762
+ }
4763
+
4764
+ results = tmp;
4765
+ }
4766
+
4767
+ return results;
4768
+ };
4769
+ }
4770
+
4771
+ div.innerHTML = "<a href='#'></a>";
4772
+ if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
4773
+ div.firstChild.getAttribute("href") !== "#" ) {
4774
+ Expr.attrHandle.href = function(elem){
4775
+ return elem.getAttribute("href", 2);
4776
+ };
4777
+ }
4778
+
4779
+ div = null; // release memory in IE
4780
+ })();
4781
+
4782
+ if ( document.querySelectorAll ) (function(){
4783
+ var oldSizzle = Sizzle, div = document.createElement("div");
4784
+ div.innerHTML = "<p class='TEST'></p>";
4785
+
4786
+ if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
4787
+ return;
4788
+ }
4789
+
4790
+ Sizzle = function(query, context, extra, seed){
4791
+ context = context || document;
4792
+
4793
+ if ( !seed && context.nodeType === 9 && !isXML(context) ) {
4794
+ try {
4795
+ return makeArray( context.querySelectorAll(query), extra );
4796
+ } catch(e){}
4797
+ }
4798
+
4799
+ return oldSizzle(query, context, extra, seed);
4800
+ };
4801
+
4802
+ for ( var prop in oldSizzle ) {
4803
+ Sizzle[ prop ] = oldSizzle[ prop ];
4804
+ }
4805
+
4806
+ div = null; // release memory in IE
4807
+ })();
4808
+
4809
+ if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) (function(){
4810
+ var div = document.createElement("div");
4811
+ div.innerHTML = "<div class='test e'></div><div class='test'></div>";
4812
+
4813
+ if ( div.getElementsByClassName("e").length === 0 )
4814
+ return;
4815
+
4816
+ div.lastChild.className = "e";
4817
+
4818
+ if ( div.getElementsByClassName("e").length === 1 )
4819
+ return;
4820
+
4821
+ Expr.order.splice(1, 0, "CLASS");
4822
+ Expr.find.CLASS = function(match, context, isXML) {
4823
+ if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
4824
+ return context.getElementsByClassName(match[1]);
4825
+ }
4826
+ };
4827
+
4828
+ div = null; // release memory in IE
4829
+ })();
4830
+
4831
+ function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
4832
+ var sibDir = dir == "previousSibling" && !isXML;
4833
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
4834
+ var elem = checkSet[i];
4835
+ if ( elem ) {
4836
+ if ( sibDir && elem.nodeType === 1 ){
4837
+ elem.sizcache = doneName;
4838
+ elem.sizset = i;
4839
+ }
4840
+ elem = elem[dir];
4841
+ var match = false;
4842
+
4843
+ while ( elem ) {
4844
+ if ( elem.sizcache === doneName ) {
4845
+ match = checkSet[elem.sizset];
4846
+ break;
4847
+ }
4848
+
4849
+ if ( elem.nodeType === 1 && !isXML ){
4850
+ elem.sizcache = doneName;
4851
+ elem.sizset = i;
4852
+ }
4853
+
4854
+ if ( elem.nodeName === cur ) {
4855
+ match = elem;
4856
+ break;
4857
+ }
4858
+
4859
+ elem = elem[dir];
4860
+ }
4861
+
4862
+ checkSet[i] = match;
4863
+ }
4864
+ }
4865
+ }
4866
+
4867
+ function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
4868
+ var sibDir = dir == "previousSibling" && !isXML;
4869
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
4870
+ var elem = checkSet[i];
4871
+ if ( elem ) {
4872
+ if ( sibDir && elem.nodeType === 1 ) {
4873
+ elem.sizcache = doneName;
4874
+ elem.sizset = i;
4875
+ }
4876
+ elem = elem[dir];
4877
+ var match = false;
4878
+
4879
+ while ( elem ) {
4880
+ if ( elem.sizcache === doneName ) {
4881
+ match = checkSet[elem.sizset];
4882
+ break;
4883
+ }
4884
+
4885
+ if ( elem.nodeType === 1 ) {
4886
+ if ( !isXML ) {
4887
+ elem.sizcache = doneName;
4888
+ elem.sizset = i;
4889
+ }
4890
+ if ( typeof cur !== "string" ) {
4891
+ if ( elem === cur ) {
4892
+ match = true;
4893
+ break;
4894
+ }
4895
+
4896
+ } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
4897
+ match = elem;
4898
+ break;
4899
+ }
4900
+ }
4901
+
4902
+ elem = elem[dir];
4903
+ }
4904
+
4905
+ checkSet[i] = match;
4906
+ }
4907
+ }
4908
+ }
4909
+
4910
+ var contains = document.compareDocumentPosition ? function(a, b){
4911
+ return a.compareDocumentPosition(b) & 16;
4912
+ } : function(a, b){
4913
+ return a !== b && (a.contains ? a.contains(b) : true);
4914
+ };
4915
+
4916
+ var isXML = function(elem){
4917
+ return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
4918
+ !!elem.ownerDocument && elem.ownerDocument.documentElement.nodeName !== "HTML";
4919
+ };
4920
+
4921
+ var posProcess = function(selector, context){
4922
+ var tmpSet = [], later = "", match,
4923
+ root = context.nodeType ? [context] : context;
4924
+
4925
+ while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
4926
+ later += match[0];
4927
+ selector = selector.replace( Expr.match.PSEUDO, "" );
4928
+ }
4929
+
4930
+ selector = Expr.relative[selector] ? selector + "*" : selector;
4931
+
4932
+ for ( var i = 0, l = root.length; i < l; i++ ) {
4933
+ Sizzle( selector, root[i], tmpSet );
4934
+ }
4935
+
4936
+ return Sizzle.filter( later, tmpSet );
4937
+ };
4938
+
4939
+
4940
+ window.Sizzle = Sizzle;
4941
+
4942
+ })();
4943
+
4944
+ ;(function(engine) {
4945
+ var extendElements = Prototype.Selector.extendElements;
4946
+
4947
+ function select(selector, scope) {
4948
+ return extendElements(engine(selector, scope || document));
4949
+ }
4950
+
4951
+ function match(element, selector) {
4952
+ return engine.matches(selector, [element]).length == 1;
4953
+ }
4954
+
4955
+ Prototype.Selector.engine = engine;
4956
+ Prototype.Selector.select = select;
4957
+ Prototype.Selector.match = match;
4958
+ })(Sizzle);
4959
+
4960
+ window.Sizzle = Prototype._original_property;
4961
+ delete Prototype._original_property;
4962
+
4963
+ var Form = {
4964
+ reset: function(form) {
4965
+ form = $(form);
4966
+ form.reset();
4967
+ return form;
4968
+ },
4969
+
4970
+ serializeElements: function(elements, options) {
4971
+ if (typeof options != 'object') options = { hash: !!options };
4972
+ else if (Object.isUndefined(options.hash)) options.hash = true;
4973
+ var key, value, submitted = false, submit = options.submit, accumulator, initial;
4974
+
4975
+ if (options.hash) {
4976
+ initial = {};
4977
+ accumulator = function(result, key, value) {
4978
+ if (key in result) {
4979
+ if (!Object.isArray(result[key])) result[key] = [result[key]];
4980
+ result[key].push(value);
4981
+ } else result[key] = value;
4982
+ return result;
4983
+ };
4984
+ } else {
4985
+ initial = '';
4986
+ accumulator = function(result, key, value) {
4987
+ return result + (result ? '&' : '') + encodeURIComponent(key) + '=' + encodeURIComponent(value);
4988
+ }
4989
+ }
4990
+
4991
+ return elements.inject(initial, function(result, element) {
4992
+ if (!element.disabled && element.name) {
4993
+ key = element.name; value = $(element).getValue();
4994
+ if (value != null && element.type != 'file' && (element.type != 'submit' || (!submitted &&
4995
+ submit !== false && (!submit || key == submit) && (submitted = true)))) {
4996
+ result = accumulator(result, key, value);
4997
+ }
4998
+ }
4999
+ return result;
5000
+ });
5001
+ }
5002
+ };
5003
+
5004
+ Form.Methods = {
5005
+ serialize: function(form, options) {
5006
+ return Form.serializeElements(Form.getElements(form), options);
5007
+ },
5008
+
5009
+ getElements: function(form) {
5010
+ var elements = $(form).getElementsByTagName('*'),
5011
+ element,
5012
+ arr = [ ],
5013
+ serializers = Form.Element.Serializers;
5014
+ for (var i = 0; element = elements[i]; i++) {
5015
+ arr.push(element);
5016
+ }
5017
+ return arr.inject([], function(elements, child) {
5018
+ if (serializers[child.tagName.toLowerCase()])
5019
+ elements.push(Element.extend(child));
5020
+ return elements;
5021
+ })
5022
+ },
5023
+
5024
+ getInputs: function(form, typeName, name) {
5025
+ form = $(form);
5026
+ var inputs = form.getElementsByTagName('input');
5027
+
5028
+ if (!typeName && !name) return $A(inputs).map(Element.extend);
5029
+
5030
+ for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) {
5031
+ var input = inputs[i];
5032
+ if ((typeName && input.type != typeName) || (name && input.name != name))
5033
+ continue;
5034
+ matchingInputs.push(Element.extend(input));
5035
+ }
5036
+
5037
+ return matchingInputs;
5038
+ },
5039
+
5040
+ disable: function(form) {
5041
+ form = $(form);
5042
+ Form.getElements(form).invoke('disable');
5043
+ return form;
5044
+ },
5045
+
5046
+ enable: function(form) {
5047
+ form = $(form);
5048
+ Form.getElements(form).invoke('enable');
5049
+ return form;
5050
+ },
5051
+
5052
+ findFirstElement: function(form) {
5053
+ var elements = $(form).getElements().findAll(function(element) {
5054
+ return 'hidden' != element.type && !element.disabled;
5055
+ });
5056
+ var firstByIndex = elements.findAll(function(element) {
5057
+ return element.hasAttribute('tabIndex') && element.tabIndex >= 0;
5058
+ }).sortBy(function(element) { return element.tabIndex }).first();
5059
+
5060
+ return firstByIndex ? firstByIndex : elements.find(function(element) {
5061
+ return /^(?:input|select|textarea)$/i.test(element.tagName);
5062
+ });
5063
+ },
5064
+
5065
+ focusFirstElement: function(form) {
5066
+ form = $(form);
5067
+ var element = form.findFirstElement();
5068
+ if (element) element.activate();
5069
+ return form;
5070
+ },
5071
+
5072
+ request: function(form, options) {
5073
+ form = $(form), options = Object.clone(options || { });
5074
+
5075
+ var params = options.parameters, action = form.readAttribute('action') || '';
5076
+ if (action.blank()) action = window.location.href;
5077
+ options.parameters = form.serialize(true);
5078
+
5079
+ if (params) {
5080
+ if (Object.isString(params)) params = params.toQueryParams();
5081
+ Object.extend(options.parameters, params);
5082
+ }
5083
+
5084
+ if (form.hasAttribute('method') && !options.method)
5085
+ options.method = form.method;
5086
+
5087
+ return new Ajax.Request(action, options);
5088
+ }
5089
+ };
5090
+
5091
+ /*--------------------------------------------------------------------------*/
5092
+
5093
+
5094
+ Form.Element = {
5095
+ focus: function(element) {
5096
+ $(element).focus();
5097
+ return element;
5098
+ },
5099
+
5100
+ select: function(element) {
5101
+ $(element).select();
5102
+ return element;
5103
+ }
5104
+ };
5105
+
5106
+ Form.Element.Methods = {
5107
+
5108
+ serialize: function(element) {
5109
+ element = $(element);
5110
+ if (!element.disabled && element.name) {
5111
+ var value = element.getValue();
5112
+ if (value != undefined) {
5113
+ var pair = { };
5114
+ pair[element.name] = value;
5115
+ return Object.toQueryString(pair);
5116
+ }
5117
+ }
5118
+ return '';
5119
+ },
5120
+
5121
+ getValue: function(element) {
5122
+ element = $(element);
5123
+ var method = element.tagName.toLowerCase();
5124
+ return Form.Element.Serializers[method](element);
5125
+ },
5126
+
5127
+ setValue: function(element, value) {
5128
+ element = $(element);
5129
+ var method = element.tagName.toLowerCase();
5130
+ Form.Element.Serializers[method](element, value);
5131
+ return element;
5132
+ },
5133
+
5134
+ clear: function(element) {
5135
+ $(element).value = '';
5136
+ return element;
5137
+ },
5138
+
5139
+ present: function(element) {
5140
+ return $(element).value != '';
5141
+ },
5142
+
5143
+ activate: function(element) {
5144
+ element = $(element);
5145
+ try {
5146
+ element.focus();
5147
+ if (element.select && (element.tagName.toLowerCase() != 'input' ||
5148
+ !(/^(?:button|reset|submit)$/i.test(element.type))))
5149
+ element.select();
5150
+ } catch (e) { }
5151
+ return element;
5152
+ },
5153
+
5154
+ disable: function(element) {
5155
+ element = $(element);
5156
+ element.disabled = true;
5157
+ return element;
5158
+ },
5159
+
5160
+ enable: function(element) {
5161
+ element = $(element);
5162
+ element.disabled = false;
5163
+ return element;
5164
+ }
5165
+ };
5166
+
5167
+ /*--------------------------------------------------------------------------*/
5168
+
5169
+ var Field = Form.Element;
5170
+
5171
+ var $F = Form.Element.Methods.getValue;
5172
+
5173
+ /*--------------------------------------------------------------------------*/
5174
+
5175
+ Form.Element.Serializers = (function() {
5176
+ function input(element, value) {
5177
+ switch (element.type.toLowerCase()) {
5178
+ case 'checkbox':
5179
+ case 'radio':
5180
+ return inputSelector(element, value);
5181
+ default:
5182
+ return valueSelector(element, value);
5183
+ }
5184
+ }
5185
+
5186
+ function inputSelector(element, value) {
5187
+ if (Object.isUndefined(value))
5188
+ return element.checked ? element.value : null;
5189
+ else element.checked = !!value;
5190
+ }
5191
+
5192
+ function valueSelector(element, value) {
5193
+ if (Object.isUndefined(value)) return element.value;
5194
+ else element.value = value;
5195
+ }
5196
+
5197
+ function select(element, value) {
5198
+ if (Object.isUndefined(value))
5199
+ return (element.type === 'select-one' ? selectOne : selectMany)(element);
5200
+
5201
+ var opt, currentValue, single = !Object.isArray(value);
5202
+ for (var i = 0, length = element.length; i < length; i++) {
5203
+ opt = element.options[i];
5204
+ currentValue = this.optionValue(opt);
5205
+ if (single) {
5206
+ if (currentValue == value) {
5207
+ opt.selected = true;
5208
+ return;
5209
+ }
5210
+ }
5211
+ else opt.selected = value.include(currentValue);
5212
+ }
5213
+ }
5214
+
5215
+ function selectOne(element) {
5216
+ var index = element.selectedIndex;
5217
+ return index >= 0 ? optionValue(element.options[index]) : null;
5218
+ }
5219
+
5220
+ function selectMany(element) {
5221
+ var values, length = element.length;
5222
+ if (!length) return null;
5223
+
5224
+ for (var i = 0, values = []; i < length; i++) {
5225
+ var opt = element.options[i];
5226
+ if (opt.selected) values.push(optionValue(opt));
5227
+ }
5228
+ return values;
5229
+ }
5230
+
5231
+ function optionValue(opt) {
5232
+ return Element.hasAttribute(opt, 'value') ? opt.value : opt.text;
5233
+ }
5234
+
5235
+ return {
5236
+ input: input,
5237
+ inputSelector: inputSelector,
5238
+ textarea: valueSelector,
5239
+ select: select,
5240
+ selectOne: selectOne,
5241
+ selectMany: selectMany,
5242
+ optionValue: optionValue,
5243
+ button: valueSelector
5244
+ };
5245
+ })();
5246
+
5247
+ /*--------------------------------------------------------------------------*/
5248
+
5249
+
5250
+ Abstract.TimedObserver = Class.create(PeriodicalExecuter, {
5251
+ initialize: function($super, element, frequency, callback) {
5252
+ $super(callback, frequency);
5253
+ this.element = $(element);
5254
+ this.lastValue = this.getValue();
5255
+ },
5256
+
5257
+ execute: function() {
5258
+ var value = this.getValue();
5259
+ if (Object.isString(this.lastValue) && Object.isString(value) ?
5260
+ this.lastValue != value : String(this.lastValue) != String(value)) {
5261
+ this.callback(this.element, value);
5262
+ this.lastValue = value;
5263
+ }
5264
+ }
5265
+ });
5266
+
5267
+ Form.Element.Observer = Class.create(Abstract.TimedObserver, {
5268
+ getValue: function() {
5269
+ return Form.Element.getValue(this.element);
5270
+ }
5271
+ });
5272
+
5273
+ Form.Observer = Class.create(Abstract.TimedObserver, {
5274
+ getValue: function() {
5275
+ return Form.serialize(this.element);
5276
+ }
5277
+ });
5278
+
5279
+ /*--------------------------------------------------------------------------*/
5280
+
5281
+ Abstract.EventObserver = Class.create({
5282
+ initialize: function(element, callback) {
5283
+ this.element = $(element);
5284
+ this.callback = callback;
5285
+
5286
+ this.lastValue = this.getValue();
5287
+ if (this.element.tagName.toLowerCase() == 'form')
5288
+ this.registerFormCallbacks();
5289
+ else
5290
+ this.registerCallback(this.element);
5291
+ },
5292
+
5293
+ onElementEvent: function() {
5294
+ var value = this.getValue();
5295
+ if (this.lastValue != value) {
5296
+ this.callback(this.element, value);
5297
+ this.lastValue = value;
5298
+ }
5299
+ },
5300
+
5301
+ registerFormCallbacks: function() {
5302
+ Form.getElements(this.element).each(this.registerCallback, this);
5303
+ },
5304
+
5305
+ registerCallback: function(element) {
5306
+ if (element.type) {
5307
+ switch (element.type.toLowerCase()) {
5308
+ case 'checkbox':
5309
+ case 'radio':
5310
+ Event.observe(element, 'click', this.onElementEvent.bind(this));
5311
+ break;
5312
+ default:
5313
+ Event.observe(element, 'change', this.onElementEvent.bind(this));
5314
+ break;
5315
+ }
5316
+ }
5317
+ }
5318
+ });
5319
+
5320
+ Form.Element.EventObserver = Class.create(Abstract.EventObserver, {
5321
+ getValue: function() {
5322
+ return Form.Element.getValue(this.element);
5323
+ }
5324
+ });
5325
+
5326
+ Form.EventObserver = Class.create(Abstract.EventObserver, {
5327
+ getValue: function() {
5328
+ return Form.serialize(this.element);
5329
+ }
5330
+ });
5331
+ (function() {
5332
+
5333
+ var Event = {
5334
+ KEY_BACKSPACE: 8,
5335
+ KEY_TAB: 9,
5336
+ KEY_RETURN: 13,
5337
+ KEY_ESC: 27,
5338
+ KEY_LEFT: 37,
5339
+ KEY_UP: 38,
5340
+ KEY_RIGHT: 39,
5341
+ KEY_DOWN: 40,
5342
+ KEY_DELETE: 46,
5343
+ KEY_HOME: 36,
5344
+ KEY_END: 35,
5345
+ KEY_PAGEUP: 33,
5346
+ KEY_PAGEDOWN: 34,
5347
+ KEY_INSERT: 45,
5348
+
5349
+ cache: {}
5350
+ };
5351
+
5352
+ var docEl = document.documentElement;
5353
+ var MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED = 'onmouseenter' in docEl
5354
+ && 'onmouseleave' in docEl;
5355
+
5356
+
5357
+
5358
+ var isIELegacyEvent = function(event) { return false; };
5359
+
5360
+ if (window.attachEvent) {
5361
+ if (window.addEventListener) {
5362
+ isIELegacyEvent = function(event) {
5363
+ return !(event instanceof window.Event);
5364
+ };
5365
+ } else {
5366
+ isIELegacyEvent = function(event) { return true; };
5367
+ }
5368
+ }
5369
+
5370
+ var _isButton;
5371
+
5372
+ function _isButtonForDOMEvents(event, code) {
5373
+ return event.which ? (event.which === code + 1) : (event.button === code);
5374
+ }
5375
+
5376
+ var legacyButtonMap = { 0: 1, 1: 4, 2: 2 };
5377
+ function _isButtonForLegacyEvents(event, code) {
5378
+ return event.button === legacyButtonMap[code];
5379
+ }
5380
+
5381
+ function _isButtonForWebKit(event, code) {
5382
+ switch (code) {
5383
+ case 0: return event.which == 1 && !event.metaKey;
5384
+ case 1: return event.which == 2 || (event.which == 1 && event.metaKey);
5385
+ case 2: return event.which == 3;
5386
+ default: return false;
5387
+ }
5388
+ }
5389
+
5390
+ if (window.attachEvent) {
5391
+ if (!window.addEventListener) {
5392
+ _isButton = _isButtonForLegacyEvents;
5393
+ } else {
5394
+ _isButton = function(event, code) {
5395
+ return isIELegacyEvent(event) ? _isButtonForLegacyEvents(event, code) :
5396
+ _isButtonForDOMEvents(event, code);
5397
+ }
5398
+ }
5399
+ } else if (Prototype.Browser.WebKit) {
5400
+ _isButton = _isButtonForWebKit;
5401
+ } else {
5402
+ _isButton = _isButtonForDOMEvents;
5403
+ }
5404
+
5405
+ function isLeftClick(event) { return _isButton(event, 0) }
5406
+
5407
+ function isMiddleClick(event) { return _isButton(event, 1) }
5408
+
5409
+ function isRightClick(event) { return _isButton(event, 2) }
5410
+
5411
+ function element(event) {
5412
+ event = Event.extend(event);
5413
+
5414
+ var node = event.target, type = event.type,
5415
+ currentTarget = event.currentTarget;
5416
+
5417
+ if (currentTarget && currentTarget.tagName) {
5418
+ if (type === 'load' || type === 'error' ||
5419
+ (type === 'click' && currentTarget.tagName.toLowerCase() === 'input'
5420
+ && currentTarget.type === 'radio'))
5421
+ node = currentTarget;
5422
+ }
5423
+
5424
+ if (node.nodeType == Node.TEXT_NODE)
5425
+ node = node.parentNode;
5426
+
5427
+ return Element.extend(node);
5428
+ }
5429
+
5430
+ function findElement(event, expression) {
5431
+ var element = Event.element(event);
5432
+
5433
+ if (!expression) return element;
5434
+ while (element) {
5435
+ if (Object.isElement(element) && Prototype.Selector.match(element, expression)) {
5436
+ return Element.extend(element);
5437
+ }
5438
+ element = element.parentNode;
5439
+ }
5440
+ }
5441
+
5442
+ function pointer(event) {
5443
+ return { x: pointerX(event), y: pointerY(event) };
5444
+ }
5445
+
5446
+ function pointerX(event) {
5447
+ var docElement = document.documentElement,
5448
+ body = document.body || { scrollLeft: 0 };
5449
+
5450
+ return event.pageX || (event.clientX +
5451
+ (docElement.scrollLeft || body.scrollLeft) -
5452
+ (docElement.clientLeft || 0));
5453
+ }
5454
+
5455
+ function pointerY(event) {
5456
+ var docElement = document.documentElement,
5457
+ body = document.body || { scrollTop: 0 };
5458
+
5459
+ return event.pageY || (event.clientY +
5460
+ (docElement.scrollTop || body.scrollTop) -
5461
+ (docElement.clientTop || 0));
5462
+ }
5463
+
5464
+
5465
+ function stop(event) {
5466
+ Event.extend(event);
5467
+ event.preventDefault();
5468
+ event.stopPropagation();
5469
+
5470
+ event.stopped = true;
5471
+ }
5472
+
5473
+
5474
+ Event.Methods = {
5475
+ isLeftClick: isLeftClick,
5476
+ isMiddleClick: isMiddleClick,
5477
+ isRightClick: isRightClick,
5478
+
5479
+ element: element,
5480
+ findElement: findElement,
5481
+
5482
+ pointer: pointer,
5483
+ pointerX: pointerX,
5484
+ pointerY: pointerY,
5485
+
5486
+ stop: stop
5487
+ };
5488
+
5489
+ var methods = Object.keys(Event.Methods).inject({ }, function(m, name) {
5490
+ m[name] = Event.Methods[name].methodize();
5491
+ return m;
5492
+ });
5493
+
5494
+ if (window.attachEvent) {
5495
+ function _relatedTarget(event) {
5496
+ var element;
5497
+ switch (event.type) {
5498
+ case 'mouseover':
5499
+ case 'mouseenter':
5500
+ element = event.fromElement;
5501
+ break;
5502
+ case 'mouseout':
5503
+ case 'mouseleave':
5504
+ element = event.toElement;
5505
+ break;
5506
+ default:
5507
+ return null;
5508
+ }
5509
+ return Element.extend(element);
5510
+ }
5511
+
5512
+ var additionalMethods = {
5513
+ stopPropagation: function() { this.cancelBubble = true },
5514
+ preventDefault: function() { this.returnValue = false },
5515
+ inspect: function() { return '[object Event]' }
5516
+ };
5517
+
5518
+ Event.extend = function(event, element) {
5519
+ if (!event) return false;
5520
+
5521
+ if (!isIELegacyEvent(event)) return event;
5522
+
5523
+ if (event._extendedByPrototype) return event;
5524
+ event._extendedByPrototype = Prototype.emptyFunction;
5525
+
5526
+ var pointer = Event.pointer(event);
5527
+
5528
+ Object.extend(event, {
5529
+ target: event.srcElement || element,
5530
+ relatedTarget: _relatedTarget(event),
5531
+ pageX: pointer.x,
5532
+ pageY: pointer.y
5533
+ });
5534
+
5535
+ Object.extend(event, methods);
5536
+ Object.extend(event, additionalMethods);
5537
+
5538
+ return event;
5539
+ };
5540
+ } else {
5541
+ Event.extend = Prototype.K;
5542
+ }
5543
+
5544
+ if (window.addEventListener) {
5545
+ Event.prototype = window.Event.prototype || document.createEvent('HTMLEvents').__proto__;
5546
+ Object.extend(Event.prototype, methods);
5547
+ }
5548
+
5549
+ function _createResponder(element, eventName, handler) {
5550
+ var registry = Element.retrieve(element, 'prototype_event_registry');
5551
+
5552
+ if (Object.isUndefined(registry)) {
5553
+ CACHE.push(element);
5554
+ registry = Element.retrieve(element, 'prototype_event_registry', $H());
5555
+ }
5556
+
5557
+ var respondersForEvent = registry.get(eventName);
5558
+ if (Object.isUndefined(respondersForEvent)) {
5559
+ respondersForEvent = [];
5560
+ registry.set(eventName, respondersForEvent);
5561
+ }
5562
+
5563
+ if (respondersForEvent.pluck('handler').include(handler)) return false;
5564
+
5565
+ var responder;
5566
+ if (eventName.include(":")) {
5567
+ responder = function(event) {
5568
+ if (Object.isUndefined(event.eventName))
5569
+ return false;
5570
+
5571
+ if (event.eventName !== eventName)
5572
+ return false;
5573
+
5574
+ Event.extend(event, element);
5575
+ handler.call(element, event);
5576
+ };
5577
+ } else {
5578
+ if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED &&
5579
+ (eventName === "mouseenter" || eventName === "mouseleave")) {
5580
+ if (eventName === "mouseenter" || eventName === "mouseleave") {
5581
+ responder = function(event) {
5582
+ Event.extend(event, element);
5583
+
5584
+ var parent = event.relatedTarget;
5585
+ while (parent && parent !== element) {
5586
+ try { parent = parent.parentNode; }
5587
+ catch(e) { parent = element; }
5588
+ }
5589
+
5590
+ if (parent === element) return;
5591
+
5592
+ handler.call(element, event);
5593
+ };
5594
+ }
5595
+ } else {
5596
+ responder = function(event) {
5597
+ Event.extend(event, element);
5598
+ handler.call(element, event);
5599
+ };
5600
+ }
5601
+ }
5602
+
5603
+ responder.handler = handler;
5604
+ respondersForEvent.push(responder);
5605
+ return responder;
5606
+ }
5607
+
5608
+ function _destroyCache() {
5609
+ for (var i = 0, length = CACHE.length; i < length; i++) {
5610
+ Event.stopObserving(CACHE[i]);
5611
+ CACHE[i] = null;
5612
+ }
5613
+ }
5614
+
5615
+ var CACHE = [];
5616
+
5617
+ if (Prototype.Browser.IE)
5618
+ window.attachEvent('onunload', _destroyCache);
5619
+
5620
+ if (Prototype.Browser.WebKit)
5621
+ window.addEventListener('unload', Prototype.emptyFunction, false);
5622
+
5623
+
5624
+ var _getDOMEventName = Prototype.K,
5625
+ translations = { mouseenter: "mouseover", mouseleave: "mouseout" };
5626
+
5627
+ if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED) {
5628
+ _getDOMEventName = function(eventName) {
5629
+ return (translations[eventName] || eventName);
5630
+ };
5631
+ }
5632
+
5633
+ function observe(element, eventName, handler) {
5634
+ element = $(element);
5635
+
5636
+ var responder = _createResponder(element, eventName, handler);
5637
+
5638
+ if (!responder) return element;
5639
+
5640
+ if (eventName.include(':')) {
5641
+ if (element.addEventListener)
5642
+ element.addEventListener("dataavailable", responder, false);
5643
+ else {
5644
+ element.attachEvent("ondataavailable", responder);
5645
+ element.attachEvent("onlosecapture", responder);
5646
+ }
5647
+ } else {
5648
+ var actualEventName = _getDOMEventName(eventName);
5649
+
5650
+ if (element.addEventListener)
5651
+ element.addEventListener(actualEventName, responder, false);
5652
+ else
5653
+ element.attachEvent("on" + actualEventName, responder);
5654
+ }
5655
+
5656
+ return element;
5657
+ }
5658
+
5659
+ function stopObserving(element, eventName, handler) {
5660
+ element = $(element);
5661
+
5662
+ var registry = Element.retrieve(element, 'prototype_event_registry');
5663
+ if (!registry) return element;
5664
+
5665
+ if (!eventName) {
5666
+ registry.each( function(pair) {
5667
+ var eventName = pair.key;
5668
+ stopObserving(element, eventName);
5669
+ });
5670
+ return element;
5671
+ }
5672
+
5673
+ var responders = registry.get(eventName);
5674
+ if (!responders) return element;
5675
+
5676
+ if (!handler) {
5677
+ responders.each(function(r) {
5678
+ stopObserving(element, eventName, r.handler);
5679
+ });
5680
+ return element;
5681
+ }
5682
+
5683
+ var i = responders.length, responder;
5684
+ while (i--) {
5685
+ if (responders[i].handler === handler) {
5686
+ responder = responders[i];
5687
+ break;
5688
+ }
5689
+ }
5690
+ if (!responder) return element;
5691
+
5692
+ if (eventName.include(':')) {
5693
+ if (element.removeEventListener)
5694
+ element.removeEventListener("dataavailable", responder, false);
5695
+ else {
5696
+ element.detachEvent("ondataavailable", responder);
5697
+ element.detachEvent("onlosecapture", responder);
5698
+ }
5699
+ } else {
5700
+ var actualEventName = _getDOMEventName(eventName);
5701
+ if (element.removeEventListener)
5702
+ element.removeEventListener(actualEventName, responder, false);
5703
+ else
5704
+ element.detachEvent('on' + actualEventName, responder);
5705
+ }
5706
+
5707
+ registry.set(eventName, responders.without(responder));
5708
+
5709
+ return element;
5710
+ }
5711
+
5712
+ function fire(element, eventName, memo, bubble) {
5713
+ element = $(element);
5714
+
5715
+ if (Object.isUndefined(bubble))
5716
+ bubble = true;
5717
+
5718
+ if (element == document && document.createEvent && !element.dispatchEvent)
5719
+ element = document.documentElement;
5720
+
5721
+ var event;
5722
+ if (document.createEvent) {
5723
+ event = document.createEvent('HTMLEvents');
5724
+ event.initEvent('dataavailable', bubble, true);
5725
+ } else {
5726
+ event = document.createEventObject();
5727
+ event.eventType = bubble ? 'ondataavailable' : 'onlosecapture';
5728
+ }
5729
+
5730
+ event.eventName = eventName;
5731
+ event.memo = memo || { };
5732
+
5733
+ if (document.createEvent)
5734
+ element.dispatchEvent(event);
5735
+ else
5736
+ element.fireEvent(event.eventType, event);
5737
+
5738
+ return Event.extend(event);
5739
+ }
5740
+
5741
+ Event.Handler = Class.create({
5742
+ initialize: function(element, eventName, selector, callback) {
5743
+ this.element = $(element);
5744
+ this.eventName = eventName;
5745
+ this.selector = selector;
5746
+ this.callback = callback;
5747
+ this.handler = this.handleEvent.bind(this);
5748
+ },
5749
+
5750
+ start: function() {
5751
+ Event.observe(this.element, this.eventName, this.handler);
5752
+ return this;
5753
+ },
5754
+
5755
+ stop: function() {
5756
+ Event.stopObserving(this.element, this.eventName, this.handler);
5757
+ return this;
5758
+ },
5759
+
5760
+ handleEvent: function(event) {
5761
+ var element = Event.findElement(event, this.selector);
5762
+ if (element) this.callback.call(this.element, event, element);
5763
+ }
5764
+ });
5765
+
5766
+ function on(element, eventName, selector, callback) {
5767
+ element = $(element);
5768
+ if (Object.isFunction(selector) && Object.isUndefined(callback)) {
5769
+ callback = selector, selector = null;
5770
+ }
5771
+
5772
+ return new Event.Handler(element, eventName, selector, callback).start();
5773
+ }
5774
+
5775
+ Object.extend(Event, Event.Methods);
5776
+
5777
+ Object.extend(Event, {
5778
+ fire: fire,
5779
+ observe: observe,
5780
+ stopObserving: stopObserving,
5781
+ on: on
5782
+ });
5783
+
5784
+ Element.addMethods({
5785
+ fire: fire,
5786
+
5787
+ observe: observe,
5788
+
5789
+ stopObserving: stopObserving,
5790
+
5791
+ on: on
5792
+ });
5793
+
5794
+ Object.extend(document, {
5795
+ fire: fire.methodize(),
5796
+
5797
+ observe: observe.methodize(),
5798
+
5799
+ stopObserving: stopObserving.methodize(),
5800
+
5801
+ on: on.methodize(),
5802
+
5803
+ loaded: false
5804
+ });
5805
+
5806
+ if (window.Event) Object.extend(window.Event, Event);
5807
+ else window.Event = Event;
5808
+ })();
5809
+
5810
+ (function() {
5811
+ /* Support for the DOMContentLoaded event is based on work by Dan Webb,
5812
+ Matthias Miller, Dean Edwards, John Resig, and Diego Perini. */
5813
+
5814
+ var timer;
5815
+
5816
+ function fireContentLoadedEvent() {
5817
+ if (document.loaded) return;
5818
+ if (timer) window.clearTimeout(timer);
5819
+ document.loaded = true;
5820
+ document.fire('dom:loaded');
5821
+ }
5822
+
5823
+ function checkReadyState() {
5824
+ if (document.readyState === 'complete') {
5825
+ document.stopObserving('readystatechange', checkReadyState);
5826
+ fireContentLoadedEvent();
5827
+ }
5828
+ }
5829
+
5830
+ function pollDoScroll() {
5831
+ try { document.documentElement.doScroll('left'); }
5832
+ catch(e) {
5833
+ timer = pollDoScroll.defer();
5834
+ return;
5835
+ }
5836
+ fireContentLoadedEvent();
5837
+ }
5838
+
5839
+ if (document.addEventListener) {
5840
+ document.addEventListener('DOMContentLoaded', fireContentLoadedEvent, false);
5841
+ } else {
5842
+ document.observe('readystatechange', checkReadyState);
5843
+ if (window == top)
5844
+ timer = pollDoScroll.defer();
5845
+ }
5846
+
5847
+ Event.observe(window, 'load', fireContentLoadedEvent);
5848
+ })();
5849
+
5850
+ Element.addMethods();
5851
+
5852
+ /*------------------------------- DEPRECATED -------------------------------*/
5853
+
5854
+ Hash.toQueryString = Object.toQueryString;
5855
+
5856
+ var Toggle = { display: Element.toggle };
5857
+
5858
+ Element.Methods.childOf = Element.Methods.descendantOf;
5859
+
5860
+ var Insertion = {
5861
+ Before: function(element, content) {
5862
+ return Element.insert(element, {before:content});
5863
+ },
5864
+
5865
+ Top: function(element, content) {
5866
+ return Element.insert(element, {top:content});
5867
+ },
5868
+
5869
+ Bottom: function(element, content) {
5870
+ return Element.insert(element, {bottom:content});
5871
+ },
5872
+
5873
+ After: function(element, content) {
5874
+ return Element.insert(element, {after:content});
5875
+ }
5876
+ };
5877
+
5878
+ var $continue = new Error('"throw $continue" is deprecated, use "return" instead');
5879
+
5880
+ var Position = {
5881
+ includeScrollOffsets: false,
5882
+
5883
+ prepare: function() {
5884
+ this.deltaX = window.pageXOffset
5885
+ || document.documentElement.scrollLeft
5886
+ || document.body.scrollLeft
5887
+ || 0;
5888
+ this.deltaY = window.pageYOffset
5889
+ || document.documentElement.scrollTop
5890
+ || document.body.scrollTop
5891
+ || 0;
5892
+ },
5893
+
5894
+ within: function(element, x, y) {
5895
+ if (this.includeScrollOffsets)
5896
+ return this.withinIncludingScrolloffsets(element, x, y);
5897
+ this.xcomp = x;
5898
+ this.ycomp = y;
5899
+ this.offset = Element.cumulativeOffset(element);
5900
+
5901
+ return (y >= this.offset[1] &&
5902
+ y < this.offset[1] + element.offsetHeight &&
5903
+ x >= this.offset[0] &&
5904
+ x < this.offset[0] + element.offsetWidth);
5905
+ },
5906
+
5907
+ withinIncludingScrolloffsets: function(element, x, y) {
5908
+ var offsetcache = Element.cumulativeScrollOffset(element);
5909
+
5910
+ this.xcomp = x + offsetcache[0] - this.deltaX;
5911
+ this.ycomp = y + offsetcache[1] - this.deltaY;
5912
+ this.offset = Element.cumulativeOffset(element);
5913
+
5914
+ return (this.ycomp >= this.offset[1] &&
5915
+ this.ycomp < this.offset[1] + element.offsetHeight &&
5916
+ this.xcomp >= this.offset[0] &&
5917
+ this.xcomp < this.offset[0] + element.offsetWidth);
5918
+ },
5919
+
5920
+ overlap: function(mode, element) {
5921
+ if (!mode) return 0;
5922
+ if (mode == 'vertical')
5923
+ return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
5924
+ element.offsetHeight;
5925
+ if (mode == 'horizontal')
5926
+ return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
5927
+ element.offsetWidth;
5928
+ },
5929
+
5930
+
5931
+ cumulativeOffset: Element.Methods.cumulativeOffset,
5932
+
5933
+ positionedOffset: Element.Methods.positionedOffset,
5934
+
5935
+ absolutize: function(element) {
5936
+ Position.prepare();
5937
+ return Element.absolutize(element);
5938
+ },
5939
+
5940
+ relativize: function(element) {
5941
+ Position.prepare();
5942
+ return Element.relativize(element);
5943
+ },
5944
+
5945
+ realOffset: Element.Methods.cumulativeScrollOffset,
5946
+
5947
+ offsetParent: Element.Methods.getOffsetParent,
5948
+
5949
+ page: Element.Methods.viewportOffset,
5950
+
5951
+ clone: function(source, target, options) {
5952
+ options = options || { };
5953
+ return Element.clonePosition(target, source, options);
5954
+ }
5955
+ };
5956
+
5957
+ /*--------------------------------------------------------------------------*/
5958
+
5959
+ if (!document.getElementsByClassName) document.getElementsByClassName = function(instanceMethods){
5960
+ function iter(name) {
5961
+ return name.blank() ? null : "[contains(concat(' ', @class, ' '), ' " + name + " ')]";
5962
+ }
5963
+
5964
+ instanceMethods.getElementsByClassName = Prototype.BrowserFeatures.XPath ?
5965
+ function(element, className) {
5966
+ className = className.toString().strip();
5967
+ var cond = /\s/.test(className) ? $w(className).map(iter).join('') : iter(className);
5968
+ return cond ? document._getElementsByXPath('.//*' + cond, element) : [];
5969
+ } : function(element, className) {
5970
+ className = className.toString().strip();
5971
+ var elements = [], classNames = (/\s/.test(className) ? $w(className) : null);
5972
+ if (!classNames && !className) return elements;
5973
+
5974
+ var nodes = $(element).getElementsByTagName('*');
5975
+ className = ' ' + className + ' ';
5976
+
5977
+ for (var i = 0, child, cn; child = nodes[i]; i++) {
5978
+ if (child.className && (cn = ' ' + child.className + ' ') && (cn.include(className) ||
5979
+ (classNames && classNames.all(function(name) {
5980
+ return !name.toString().blank() && cn.include(' ' + name + ' ');
5981
+ }))))
5982
+ elements.push(Element.extend(child));
5983
+ }
5984
+ return elements;
5985
+ };
5986
+
5987
+ return function(className, parentElement) {
5988
+ return $(parentElement || document.body).getElementsByClassName(className);
5989
+ };
5990
+ }(Element.Methods);
5991
+
5992
+ /*--------------------------------------------------------------------------*/
5993
+
5994
+ Element.ClassNames = Class.create();
5995
+ Element.ClassNames.prototype = {
5996
+ initialize: function(element) {
5997
+ this.element = $(element);
5998
+ },
5999
+
6000
+ _each: function(iterator) {
6001
+ this.element.className.split(/\s+/).select(function(name) {
6002
+ return name.length > 0;
6003
+ })._each(iterator);
6004
+ },
6005
+
6006
+ set: function(className) {
6007
+ this.element.className = className;
6008
+ },
6009
+
6010
+ add: function(classNameToAdd) {
6011
+ if (this.include(classNameToAdd)) return;
6012
+ this.set($A(this).concat(classNameToAdd).join(' '));
6013
+ },
6014
+
6015
+ remove: function(classNameToRemove) {
6016
+ if (!this.include(classNameToRemove)) return;
6017
+ this.set($A(this).without(classNameToRemove).join(' '));
6018
+ },
6019
+
6020
+ toString: function() {
6021
+ return $A(this).join(' ');
6022
+ }
6023
+ };
6024
+
6025
+ Object.extend(Element.ClassNames.prototype, Enumerable);
6026
+
6027
+ /*--------------------------------------------------------------------------*/
6028
+
6029
+ (function() {
6030
+ window.Selector = Class.create({
6031
+ initialize: function(expression) {
6032
+ this.expression = expression.strip();
6033
+ },
6034
+
6035
+ findElements: function(rootElement) {
6036
+ return Prototype.Selector.select(this.expression, rootElement);
6037
+ },
6038
+
6039
+ match: function(element) {
6040
+ return Prototype.Selector.match(element, this.expression);
6041
+ },
6042
+
6043
+ toString: function() {
6044
+ return this.expression;
6045
+ },
6046
+
6047
+ inspect: function() {
6048
+ return "#<Selector: " + this.expression + ">";
6049
+ }
6050
+ });
6051
+
6052
+ Object.extend(Selector, {
6053
+ matchElements: function(elements, expression) {
6054
+ var match = Prototype.Selector.match,
6055
+ results = [];
6056
+
6057
+ for (var i = 0, length = elements.length; i < length; i++) {
6058
+ var element = elements[i];
6059
+ if (match(element, expression)) {
6060
+ results.push(Element.extend(element));
6061
+ }
6062
+ }
6063
+ return results;
6064
+ },
6065
+
6066
+ findElement: function(elements, expression, index) {
6067
+ index = index || 0;
6068
+ var matchIndex = 0, element;
6069
+ for (var i = 0, length = elements.length; i < length; i++) {
6070
+ element = elements[i];
6071
+ if (Prototype.Selector.match(element, expression) && index === matchIndex++) {
6072
+ return Element.extend(element);
6073
+ }
6074
+ }
6075
+ },
6076
+
6077
+ findChildElements: function(element, expressions) {
6078
+ var selector = expressions.toArray().join(', ');
6079
+ return Prototype.Selector.select(selector, element || document);
6080
+ }
6081
+ });
6082
+ })();
pages/lists.php CHANGED
@@ -402,7 +402,7 @@
402
  });
403
 
404
  // append remove button to end of subscriber on hover
405
- jQuery('.yks_mc_subscribers').delegate('.yks-mailchimp-subscribers-list-row', 'mouseenter', function() {
406
  var user_email_href = jQuery(this).find('.subscriber-mail-link').attr('rel');
407
  jQuery(this).find('td:last-child').append('<span class="yks-remove-subscriber dashicons dashicons-no-alt"></span>');
408
  jQuery(this).find('td:last-child').append('<a href="'+user_email_href+'" class="yks-email-subscriber dashicons dashicons-email-alt"></a>');
402
  });
403
 
404
  // append remove button to end of subscriber on hover
405
+ jQuery('.yks_mc_subscribers').undelegate('.yks-mailchimp-subscribers-list-row', 'mouseenter' ).delegate('.yks-mailchimp-subscribers-list-row', 'mouseenter', function() {
406
  var user_email_href = jQuery(this).find('.subscriber-mail-link').attr('rel');
407
  jQuery(this).find('td:last-child').append('<span class="yks-remove-subscriber dashicons dashicons-no-alt"></span>');
408
  jQuery(this).find('td:last-child').append('<a href="'+user_email_href+'" class="yks-email-subscriber dashicons dashicons-email-alt"></a>');
pages/myMailChimp.php CHANGED
@@ -1,233 +1,249 @@
1
- <style>
2
- .asbestos-flat-button {
3
- position: relative;
4
- vertical-align: top;
5
- width: 19.84%;
6
- height: 70px;
7
- padding: 0;
8
- font-size: 16px;
9
- color:white;
10
- text-align: center;
11
- text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
12
- background: #7f8c8d;
13
- border: 0;
14
- border-bottom: 2px solid #6d7b7c;
15
- cursor: pointer;
16
- -webkit-box-shadow: inset 0 -2px #6d7b7c;
17
- box-shadow: inset 0 -2px #6d7b7c;
18
- margin-top: .5em;
19
- }
20
- .asbestos-flat-button:active {
21
- top: 1px;
22
- outline: none;
23
- -webkit-box-shadow: none;
24
- box-shadow: none;
25
- }
26
- .mailChimp_get_subscribers_preloader {
27
- margin-top: 0;
28
- padding-top:3.5em;
29
- }
30
- </style>
31
- <?php
32
- // My MailChimp Page
33
- // List Stats, Notifications, etc.
34
- // We can utilize chart.js to display
35
- // statistics etc.
36
-
37
- // used to dictate the active tab
38
- $active_tab = isset( $_GET[ 'tab' ] ) ? $_GET[ 'tab' ] : 'account_overview';
39
- ?>
40
-
41
- <div class="wrap">
42
-
43
- <!-- yikes logo on all settings pages -->
44
- <div id="yks_mc_review_this_plugin_container">
45
- <a href="https://github.com/yikesinc/yikes-inc-easy-mailchimp-extender/issues?state=open" target="_blank">
46
- <span class="yks_mc_need_support">
47
- <strong>
48
- <?php _e( 'Need Help?', 'yikes-inc-easy-mailchimp-extender' ); ?> <br />
49
- <?php _e( 'Get In Contact!', 'yikes-inc-easy-mailchimp-extender' ); ?> <br />
50
- <div class="dashicons dashicons-plus-alt"></div>
51
- </strong>
52
- </span>
53
- </a>
54
- <a href="http://wordpress.org/support/view/plugin-reviews/yikes-inc-easy-mailchimp-extender" target="_blank">
55
- <span class="yks_mc_leave_us_a_review">
56
- <strong>
57
- <?php _e( 'Loving the plugin?', 'yikes-inc-easy-mailchimp-extender' ); ?> <br />
58
- <?php _e( 'Leave us a nice review', 'yikes-inc-easy-mailchimp-extender' ); ?> <br />
59
- <div class="dashicons dashicons-star-filled"></div><div class="dashicons dashicons-star-filled"></div><div class="dashicons dashicons-star-filled"></div><div class="dashicons dashicons-star-filled"></div><div class="dashicons dashicons-star-filled"></div>
60
- </strong>
61
- </span>
62
- </a>
63
- <a href="http://www.yikesinc.com" target="_blank" class="yks_header_logo">
64
- <img src="<?php echo plugins_url().'/yikes-inc-easy-mailchimp-extender/images/yikes_logo.png'; ?>" alt="YIKES Inc. Logo" width=85 title="YIKES Inc. Logo" />
65
- </a>
66
- </div>
67
-
68
-
69
-
70
- <div id="ykseme-icon" class="icon32"></div>
71
-
72
- <!-- Page Header -->
73
- <h2 id="ykseme-page-header">
74
- <?php _e('Easy Mailchimp Forms by YIKES, Inc.','yikes-inc-easy-mailchimp-extender'); ?>
75
- </h2>
76
-
77
- <h2 class="yks-mc-no-print"><?php _e( 'My MailChimp' , 'yikes-inc-easy-mailchimp-extender' ); ?></h2>
78
- <p class="yks-mc-no-print"><?php _e( 'Here you will find recent activity for your MailChimp account, as well as statistics for lists and campaigns.' , 'yikes-inc-easy-mailchimp-extender' ); ?></p>
79
- <br />
80
-
81
- <!-- tabs -->
82
- <h2 class="nav-tab-wrapper account-nav-tab yks-mc-no-print">
83
- <a href="?page=yks-mailchimp-my-mailchimp&tab=account_overview" class="nav-tab <?php echo $active_tab == 'account_overview' ? 'nav-tab-active' : ''; ?>"><?php _e('Account Overview','yikes-inc-easy-mailchimp-extender'); ?></a>
84
- <a href="?page=yks-mailchimp-my-mailchimp&tab=chimp_chatter" class="nav-tab <?php echo $active_tab == 'chimp_chatter' ? 'nav-tab-active' : ''; ?>"><?php _e('Account Activity','yikes-inc-easy-mailchimp-extender'); ?></a>
85
- <a href="?page=yks-mailchimp-my-mailchimp&tab=list_stats" class="nav-tab <?php echo $active_tab == 'list_stats' ? 'nav-tab-active' : ''; ?>"><?php _e('List Statistics','yikes-inc-easy-mailchimp-extender'); ?></a>
86
- </h2>
87
-
88
- <?php if ( $active_tab == 'account_overview' ) { ?>
89
-
90
- <script type="text/javascript">
91
- jQuery(document).ready(function() {
92
- var apiKey = '<?php echo $this->optionVal['api-key']; ?>';
93
-
94
- // post the data to our MailChimp Get User Account Details function inside of lib.ajax.php
95
- jQuery.ajax({
96
- type: 'POST',
97
- url: ajaxurl,
98
- data: {
99
- action: 'yks_mailchimp_form',
100
- form_action: 'get_profile_details',
101
- api_key: apiKey
102
- },
103
- dataType: 'html',
104
- success: function(response) {
105
- jQuery('.mailChimpChatterDiv').prepend('<div>'+response+'</div>');
106
- jQuery('.mailChimp_get_subscribers_preloader').remove();
107
- },
108
- error: function(response) {
109
- jQuery('.mailChimpChatterDiv').append('<p class="no_data_found">There was an error retreiving your account information.</p>');
110
- }
111
- });
112
-
113
-
114
- });
115
-
116
-
117
-
118
- </script>
119
-
120
- <!-- Recent Activity Header + Table -->
121
- <div class="mailChimpChatterDiv">
122
- <img class="mailChimp_get_subscribers_preloader" src="<?php echo admin_url().'/images/wpspin_light.gif'; ?>" alt="preloader" >
123
- </div>
124
- <?php
125
- echo '<span style="display:block;float:left;width:100%;font-size:1.25em;font-weight:bold;text-align:right;margin-top:2.5em;"><hr /> This plugin was created by <a href="http://www.yikesinc.com" target="_blank">YIKES Inc.</a></span>';
126
- }
127
-
128
- if ( $active_tab == 'chimp_chatter' ) { ?>
129
- <script type="text/javascript">
130
- jQuery(document).ready(function() {
131
- var apiKey = '<?php echo $this->optionVal['api-key']; ?>';
132
- jQuery('#yks-mailchimp-api-key').val();
133
- // store datacenter value, from end of api key
134
- var dataCenter = apiKey.substr(apiKey.indexOf("-") + 1);
135
-
136
- // post the data to our MailChimp Chatter function inside of lib.ajax.php
137
- jQuery.ajax({
138
- type: 'POST',
139
- url: ajaxurl,
140
- data: {
141
- action: 'yks_mailchimp_form',
142
- form_action: 'yks_get_chimp_chatter',
143
- api_key: apiKey,
144
- data_center: dataCenter
145
- },
146
- dataType: 'html',
147
- success: function(response) {
148
- jQuery('.mailChimpChatterDiv').html('<div>'+response+'</div>');
149
- jQuery("table td:nth-child(4)").each(function() {
150
- jQuery(this).filter(function(){
151
- var html = jQuery(this).html();
152
- var emailPattern = /[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}/g;
153
- var matched_str = jQuery(this).html().match(emailPattern);
154
- var matched_str = jQuery(this).html().match(emailPattern);
155
- if(matched_str){
156
- var text = jQuery(this).html();
157
- jQuery.each(matched_str, function(index, value){
158
- text = text.replace(value,"<a href='mailto:"+value+"'>"+value+"</a>");
159
- });
160
- jQuery(this).html(text);
161
- return jQuery(this)
162
- }
163
- });
164
- });
165
- },
166
- error: function(response) {
167
- jQuery('.nav-tab-wrapper').after('<p style="width:100%;text-align:center;margin:1em 0;">There was an error processing your request. Please try again. If this error persists, please open a support thread <a href="https://github.com/yikesinc/yikes-inc-easy-mailchimp-extender" title="Yikes Inc Easy MailChimp GitHub Issue Tracker" target="_blank">here</a>.</p>');
168
- }
169
- });
170
- });
171
- </script>
172
- <!-- Recent Activity Header + Table -->
173
- <h3 class="statistics-sub-title"><?php _e('Recent Activity','yikes-inc-easy-mailchimp-extender'); ?></h3>
174
- <div class="mailChimpChatterDiv">
175
- <img class="mailChimp_get_subscribers_preloader" src="<?php echo admin_url().'/images/wpspin_light.gif'; ?>" alt="preloader" >
176
- </div>
177
- <?php
178
- echo '<span style="display:block;float:left;width:100%;font-size:1.25em;font-weight:bold;text-align:right;margin-top:2.5em;"><hr /> This plugin was created by <a href="http://www.yikesinc.com" target="_blank">YIKES Inc.</a></span>';
179
- }
180
-
181
- if ( $active_tab == 'list_stats' ) { ?>
182
-
183
- <script type="text/javascript">
184
- jQuery(document).ready(function() {
185
- var apiKey = '<?php echo $this->optionVal['api-key']; ?>';
186
- // post the data to our get growth list data
187
- // function inside of lib.ajax.php
188
- jQuery.ajax({
189
- type: 'POST',
190
- url: ajaxurl,
191
- data: {
192
- action: 'yks_mailchimp_form',
193
- form_action: 'yks_get_growth_data',
194
- api_key: apiKey
195
- },
196
- dataType: 'html',
197
- success: function(response) {
198
- // on success refresh our stats chart
199
- jQuery('.mailChimpStatisticsDiv').html('<div>'+response+'</div>');
200
- }
201
- });
202
- });
203
- </script>
204
-
205
- <!-- Recent Activity Header + Table -->
206
- <div style="margin:1em 0;">
207
- <h3 class="statistics-sub-title button-secondary growth-history-button active-parent-button"><?php _e('Growth History','yikes-inc-easy-mailchimp-extender'); ?></h3>
208
- <h3 class="statistics-sub-title button-secondary campaign-stats-button"><?php _e('Campaign Stats','yikes-inc-easy-mailchimp-extender'); ?></h3>
209
- </div>
210
-
211
- <div class="mailChimpStatisticsDiv" style="min-height:400px;width:100%;">
212
- <img class="mailChimp_get_subscribers_preloader" style="display:block;margin:0 auto;" src="<?php echo admin_url().'/images/wpspin_light.gif'; ?>" alt="preloader" >
213
- </div>
214
-
215
- <div id="click_tracking_info"></div>
216
-
217
- <div id="geo_data_link_map"></div>
218
-
219
- <div id="interactive_list_items">
220
- <?php
221
- $this->getListsForStats();
222
- ?>
223
- </div>
224
- <div id="interactive_campaigns">
225
-
226
- </div>
227
- <?php
228
- echo '<span style="display:block;float:left;width:100%;font-size:1.25em;font-weight:bold;text-align:right;margin-top:2.5em;"><hr /> This plugin was created by <a href="http://www.yikesinc.com" target="_blank">YIKES Inc.</a></span>';
229
-
230
- } // end list_stats page
231
- ?>
232
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
233
  </div>
1
+ <style>
2
+ .asbestos-flat-button {
3
+ position: relative;
4
+ vertical-align: top;
5
+ width: 19.84%;
6
+ height: 70px;
7
+ padding: 0;
8
+ font-size: 16px;
9
+ color:white;
10
+ text-align: center;
11
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
12
+ background: #7f8c8d;
13
+ border: 0;
14
+ border-bottom: 2px solid #6d7b7c;
15
+ cursor: pointer;
16
+ -webkit-box-shadow: inset 0 -2px #6d7b7c;
17
+ box-shadow: inset 0 -2px #6d7b7c;
18
+ margin-top: .5em;
19
+ }
20
+ .asbestos-flat-button:active {
21
+ top: 1px;
22
+ outline: none;
23
+ -webkit-box-shadow: none;
24
+ box-shadow: none;
25
+ }
26
+ .mailChimp_get_subscribers_preloader {
27
+ margin-top: 0;
28
+ padding-top:3.5em;
29
+ }
30
+ </style>
31
+ <?php
32
+ // My MailChimp Page
33
+ // List Stats, Notifications, etc.
34
+ // We can utilize chart.js to display
35
+ // statistics etc.
36
+
37
+ // used to dictate the active tab
38
+ $active_tab = isset( $_GET[ 'tab' ] ) ? $_GET[ 'tab' ] : 'account_overview';
39
+ ?>
40
+
41
+ <div class="wrap">
42
+
43
+ <!-- yikes logo on all settings pages -->
44
+ <div id="yks_mc_review_this_plugin_container">
45
+ <a href="https://github.com/yikesinc/yikes-inc-easy-mailchimp-extender/issues?state=open" target="_blank">
46
+ <span class="yks_mc_need_support">
47
+ <strong>
48
+ <?php _e( 'Need Help?', 'yikes-inc-easy-mailchimp-extender' ); ?> <br />
49
+ <?php _e( 'Get In Contact!', 'yikes-inc-easy-mailchimp-extender' ); ?> <br />
50
+ <div class="dashicons dashicons-plus-alt"></div>
51
+ </strong>
52
+ </span>
53
+ </a>
54
+ <a href="http://wordpress.org/support/view/plugin-reviews/yikes-inc-easy-mailchimp-extender" target="_blank">
55
+ <span class="yks_mc_leave_us_a_review">
56
+ <strong>
57
+ <?php _e( 'Loving the plugin?', 'yikes-inc-easy-mailchimp-extender' ); ?> <br />
58
+ <?php _e( 'Leave us a nice review', 'yikes-inc-easy-mailchimp-extender' ); ?> <br />
59
+ <div class="dashicons dashicons-star-filled"></div><div class="dashicons dashicons-star-filled"></div><div class="dashicons dashicons-star-filled"></div><div class="dashicons dashicons-star-filled"></div><div class="dashicons dashicons-star-filled"></div>
60
+ </strong>
61
+ </span>
62
+ </a>
63
+ <a href="http://www.yikesinc.com" target="_blank" class="yks_header_logo">
64
+ <img src="<?php echo plugins_url().'/yikes-inc-easy-mailchimp-extender/images/yikes_logo.png'; ?>" alt="YIKES Inc. Logo" width=85 title="YIKES Inc. Logo" />
65
+ </a>
66
+ </div>
67
+
68
+
69
+
70
+ <div id="ykseme-icon" class="icon32"></div>
71
+
72
+ <!-- Page Header -->
73
+ <h2 id="ykseme-page-header">
74
+ <?php _e('Easy Mailchimp Forms by YIKES, Inc.','yikes-inc-easy-mailchimp-extender'); ?>
75
+ </h2>
76
+
77
+ <h2 class="yks-mc-no-print"><?php _e( 'My MailChimp' , 'yikes-inc-easy-mailchimp-extender' ); ?></h2>
78
+ <p class="yks-mc-no-print"><?php _e( 'Here you will find recent activity for your MailChimp account, as well as statistics for lists and campaigns.' , 'yikes-inc-easy-mailchimp-extender' ); ?></p>
79
+ <br />
80
+
81
+ <!-- tabs -->
82
+ <h2 class="nav-tab-wrapper account-nav-tab yks-mc-no-print">
83
+ <a href="?page=yks-mailchimp-my-mailchimp&tab=account_overview" class="nav-tab <?php echo $active_tab == 'account_overview' ? 'nav-tab-active' : ''; ?>"><?php _e('Account Overview','yikes-inc-easy-mailchimp-extender'); ?></a>
84
+ <a href="?page=yks-mailchimp-my-mailchimp&tab=chimp_chatter" class="nav-tab <?php echo $active_tab == 'chimp_chatter' ? 'nav-tab-active' : ''; ?>"><?php _e('Account Activity','yikes-inc-easy-mailchimp-extender'); ?></a>
85
+ <a href="?page=yks-mailchimp-my-mailchimp&tab=list_stats" class="nav-tab <?php echo $active_tab == 'list_stats' ? 'nav-tab-active' : ''; ?>"><?php _e('List Statistics','yikes-inc-easy-mailchimp-extender'); ?></a>
86
+ </h2>
87
+
88
+ <?php if ( $active_tab == 'account_overview' ) { ?>
89
+
90
+ <script type="text/javascript">
91
+ jQuery(document).ready(function() {
92
+ var apiKey = '<?php echo $this->optionVal['api-key']; ?>';
93
+
94
+ // post the data to our MailChimp Get User Account Details function inside of lib.ajax.php
95
+ jQuery.ajax({
96
+ type: 'POST',
97
+ url: ajaxurl,
98
+ data: {
99
+ action: 'yks_mailchimp_form',
100
+ form_action: 'get_profile_details',
101
+ api_key: apiKey
102
+ },
103
+ dataType: 'html',
104
+ success: function(response) {
105
+ jQuery('.mailChimpChatterDiv').prepend('<div>'+response+'</div>');
106
+ jQuery('.mailChimp_get_subscribers_preloader').remove();
107
+ },
108
+ error: function(response) {
109
+ jQuery('.mailChimpChatterDiv').append('<p class="no_data_found">There was an error retreiving your account information.</p>');
110
+ }
111
+ });
112
+
113
+
114
+ });
115
+
116
+
117
+
118
+ </script>
119
+
120
+ <!-- Recent Activity Header + Table -->
121
+ <div class="mailChimpChatterDiv">
122
+ <img class="mailChimp_get_subscribers_preloader" src="<?php echo admin_url().'/images/wpspin_light.gif'; ?>" alt="preloader" >
123
+ </div>
124
+ <?php
125
+ echo '<span style="display:block;float:left;width:100%;font-size:1.25em;font-weight:bold;text-align:right;margin-top:2.5em;"><hr /> This plugin was created by <a href="http://www.yikesinc.com" target="_blank">YIKES Inc.</a></span>';
126
+ }
127
+
128
+ if ( $active_tab == 'chimp_chatter' ) { ?>
129
+ <script type="text/javascript">
130
+ jQuery(document).ready(function() {
131
+ var apiKey = '<?php echo $this->optionVal['api-key']; ?>';
132
+ jQuery('#yks-mailchimp-api-key').val();
133
+ // store datacenter value, from end of api key
134
+ var dataCenter = apiKey.substr(apiKey.indexOf("-") + 1);
135
+
136
+ // post the data to our MailChimp Chatter function inside of lib.ajax.php
137
+ jQuery.ajax({
138
+ type: 'POST',
139
+ url: ajaxurl,
140
+ data: {
141
+ action: 'yks_mailchimp_form',
142
+ form_action: 'yks_get_chimp_chatter',
143
+ api_key: apiKey,
144
+ data_center: dataCenter
145
+ },
146
+ dataType: 'html',
147
+ success: function(response) {
148
+
149
+ // create hidden input fields to store our returned data for comparison
150
+ // create our new chimp chatter response field
151
+ jQuery('.mailChimpChatterDiv').before('<div style="display:none;" id="new_chimp_chatter_response"></div>');
152
+ // create our original chimp chatter response
153
+ jQuery('.mailChimpChatterDiv').before('<div style="display:none;" id="original_chimp_chatter_response"></div>');
154
+
155
+ // populate the original chimp chatter input with our original response
156
+ jQuery('#original_chimp_chatter_response').html(response);
157
+
158
+ // populate the visible chimp chatter div with the content
159
+ // on original page load
160
+ jQuery('.mailChimpChatterDiv').not('#original_chimp_chatter_response').not('#new_chimp_chatter_response').html(response);
161
+
162
+ // loop over the visible user facing table and wrap
163
+ // each email with an <a> tag with mailto: attribute
164
+ jQuery("table#yks-admin-chimp-chatter td:nth-child(4)").each(function() {
165
+ jQuery(this).filter(function(){
166
+ var html = jQuery(this).html();
167
+ var emailPattern = /[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}/g;
168
+ var matched_str = jQuery(this).html().match(emailPattern);
169
+ var matched_str = jQuery(this).html().match(emailPattern);
170
+ if(matched_str){
171
+ var text = jQuery(this).html();
172
+ jQuery.each(matched_str, function(index, value){
173
+ text = text.replace(value,"<a href='mailto:"+value+"'>"+value+"</a>");
174
+ });
175
+ jQuery(this).html(text);
176
+ return jQuery(this)
177
+ }
178
+ });
179
+ });
180
+
181
+ },
182
+ error: function(response) {
183
+ jQuery('.nav-tab-wrapper').after('<p style="width:100%;text-align:center;margin:1em 0;">There was an error processing your request. Please try again. If this error persists, please open a support thread <a href="https://github.com/yikesinc/yikes-inc-easy-mailchimp-extender" title="Yikes Inc Easy MailChimp GitHub Issue Tracker" target="_blank">here</a>.</p>');
184
+ }
185
+ });
186
+ });
187
+ </script>
188
+ <!-- Recent Activity Header + Table -->
189
+ <h3 class="statistics-sub-title"><?php _e('Recent Activity','yikes-inc-easy-mailchimp-extender'); ?></h3>
190
+ <div class="mailChimpChatterDiv">
191
+ <img class="mailChimp_get_subscribers_preloader" src="<?php echo admin_url().'/images/wpspin_light.gif'; ?>" alt="preloader" >
192
+ </div>
193
+ <?php
194
+ echo '<span style="display:block;float:left;width:100%;font-size:1.25em;font-weight:bold;text-align:right;margin-top:2.5em;"><hr /> This plugin was created by <a href="http://www.yikesinc.com" target="_blank">YIKES Inc.</a></span>';
195
+ }
196
+
197
+ if ( $active_tab == 'list_stats' ) { ?>
198
+
199
+ <script type="text/javascript">
200
+ jQuery(document).ready(function() {
201
+ var apiKey = '<?php echo $this->optionVal['api-key']; ?>';
202
+ // post the data to our get growth list data
203
+ // function inside of lib.ajax.php
204
+ jQuery.ajax({
205
+ type: 'POST',
206
+ url: ajaxurl,
207
+ data: {
208
+ action: 'yks_mailchimp_form',
209
+ form_action: 'yks_get_growth_data',
210
+ api_key: apiKey
211
+ },
212
+ dataType: 'html',
213
+ success: function(response) {
214
+ // on success refresh our stats chart
215
+ jQuery('.mailChimpStatisticsDiv').html('<div>'+response+'</div>');
216
+ }
217
+ });
218
+ });
219
+ </script>
220
+
221
+ <!-- Recent Activity Header + Table -->
222
+ <div style="margin:1em 0;">
223
+ <h3 class="statistics-sub-title button-secondary growth-history-button active-parent-button"><?php _e('Growth History','yikes-inc-easy-mailchimp-extender'); ?></h3>
224
+ <h3 class="statistics-sub-title button-secondary campaign-stats-button"><?php _e('Campaign Stats','yikes-inc-easy-mailchimp-extender'); ?></h3>
225
+ </div>
226
+
227
+ <div class="mailChimpStatisticsDiv" style="min-height:400px;width:100%;">
228
+ <img class="mailChimp_get_subscribers_preloader" style="display:block;margin:0 auto;" src="<?php echo admin_url().'/images/wpspin_light.gif'; ?>" alt="preloader" >
229
+ </div>
230
+
231
+ <div id="click_tracking_info"></div>
232
+
233
+ <div id="geo_data_link_map"></div>
234
+
235
+ <div id="interactive_list_items">
236
+ <?php
237
+ $this->getListsForStats();
238
+ ?>
239
+ </div>
240
+ <div id="interactive_campaigns">
241
+
242
+ </div>
243
+ <?php
244
+ echo '<span style="display:block;float:left;width:100%;font-size:1.25em;font-weight:bold;text-align:right;margin-top:2.5em;"><hr /> This plugin was created by <a href="http://www.yikesinc.com" target="_blank">YIKES Inc.</a></span>';
245
+
246
+ } // end list_stats page
247
+ ?>
248
+
249
  </div>
pages/options.php CHANGED
@@ -317,7 +317,6 @@ jQuery(document).ready(function() {
317
  $active_tab = isset( $_GET[ 'tab' ] ) ? $_GET[ 'tab' ] : 'form_options';
318
  ?>
319
  <div class="wrap">
320
-
321
  <!-- yikes logo on all settings pages -->
322
  <div id="yks_mc_review_this_plugin_container">
323
  <a href="https://github.com/yikesinc/yikes-inc-easy-mailchimp-extender/issues?state=open" target="_blank">
@@ -369,6 +368,17 @@ jQuery(document).ready(function() {
369
  </div>
370
  <?php }
371
 
 
 
 
 
 
 
 
 
 
 
 
372
  // check if the user is on localhost
373
  // if so, they need to enable SSL on localhost
374
  if ( $this->yks_mc_is_user_localhost() ) {
@@ -524,9 +534,7 @@ jQuery(document).ready(function() {
524
  </table>
525
  </form>
526
 
527
- <?php } else if ( $active_tab == 'recaptcha_settings' ) { ?>
528
-
529
- <!-- START RECAPTCHA SETTINGS PAGE -->
530
 
531
  <h3><?php _e('ReCaptcha Settings','yikes-inc-easy-mailchimp-extender'); ?></h3>
532
  <p class="yks-settings-description"><?php _e('reCAPTCHA is a free service to protect your website from spam and abuse. reCAPTCHA uses an advanced risk analysis engine and adaptive CAPTCHAs to keep automated software from engaging in abusive activities on your site. It does this while letting your valid users pass through with ease.','yikes-inc-easy-mailchimp-extender'); ?></p>
@@ -553,7 +561,6 @@ jQuery(document).ready(function() {
553
  <em><?php _e('ReCaptcha prevents excessive form entires from spammers and bots.','yikes-inc-easy-mailchimp-extender'); ?></em>
554
  </td>
555
  </tr>
556
-
557
  <!-- ReCaptcha Input Fields -->
558
  <!-- hidden until ReCaptcha option is enabled -->
559
  <tr valign="top" class="recaptcha-settings-hidden-container" <?php if ( $this->optionVal['recaptcha-setting'] === '0' ) { ?> style="display:none;" <?php } ?>>
317
  $active_tab = isset( $_GET[ 'tab' ] ) ? $_GET[ 'tab' ] : 'form_options';
318
  ?>
319
  <div class="wrap">
 
320
  <!-- yikes logo on all settings pages -->
321
  <div id="yks_mc_review_this_plugin_container">
322
  <a href="https://github.com/yikesinc/yikes-inc-easy-mailchimp-extender/issues?state=open" target="_blank">
368
  </div>
369
  <?php }
370
 
371
+
372
+ if( !function_exists( 'mcrypt_module_open' ) ) {
373
+ ?>
374
+ <div class="error">
375
+ <h3><div class="dashicons dashicons-no yks_mc_error_x"></div><?php _e( 'Encryption Module Not Installed', 'yikes-inc-easy-mailchimp-extender' ); ?></h3>
376
+ <p><?php _e( "We're sorry, but it looks like you don't have the php mcrpyt module installed. This module is used to encrpyt your API key for security purposes. Please install mcrypt. If you are unsure how, please contact your host provider.", "yikes-inc-easy-mailchimp-extender" ); ?></p>
377
+ </div
378
+ <?php
379
+ }
380
+
381
+
382
  // check if the user is on localhost
383
  // if so, they need to enable SSL on localhost
384
  if ( $this->yks_mc_is_user_localhost() ) {
534
  </table>
535
  </form>
536
 
537
+ <?php } else if ( $active_tab == 'recaptcha_settings' ) { ?>
 
 
538
 
539
  <h3><?php _e('ReCaptcha Settings','yikes-inc-easy-mailchimp-extender'); ?></h3>
540
  <p class="yks-settings-description"><?php _e('reCAPTCHA is a free service to protect your website from spam and abuse. reCAPTCHA uses an advanced risk analysis engine and adaptive CAPTCHAs to keep automated software from engaging in abusive activities on your site. It does this while letting your valid users pass through with ease.','yikes-inc-easy-mailchimp-extender'); ?></p>
561
  <em><?php _e('ReCaptcha prevents excessive form entires from spammers and bots.','yikes-inc-easy-mailchimp-extender'); ?></em>
562
  </td>
563
  </tr>
 
564
  <!-- ReCaptcha Input Fields -->
565
  <!-- hidden until ReCaptcha option is enabled -->
566
  <tr valign="top" class="recaptcha-settings-hidden-container" <?php if ( $this->optionVal['recaptcha-setting'] === '0' ) { ?> style="display:none;" <?php } ?>>
process/ajax.php CHANGED
@@ -132,6 +132,10 @@ case 'yks_get_subscriberInfo':
132
 
133
  case 'yks_get_chimp_chatter':
134
  $validate_action = $yksemeBase->getMailChimpChatter($_POST);
 
 
 
 
135
  break;
136
 
137
  case 'yks_get_growth_data':
132
 
133
  case 'yks_get_chimp_chatter':
134
  $validate_action = $yksemeBase->getMailChimpChatter($_POST);
135
+ break;
136
+
137
+ case 'yks_get_widget_chimp_chatter':
138
+ $validate_action = $yksemeBase->getMailChimpChatterForWidget($_POST);
139
  break;
140
 
141
  case 'yks_get_growth_data':
readme.md CHANGED
@@ -414,13 +414,45 @@ These functions should be used in conjunction with the `yikes_mc_get_form_data`
414
 
415
  Changes
416
  ===========
417
- * Added reCAPTCHA support to prevent bots and spammers from submitting forms
418
- * Split settings page into three seperate sections
419
- * Removed Jetpack sharing icons from appearing in the success messages (removed sharedaddy filter)
420
- * Updated translation files with new strings
421
- * Update existing screen shots and add new screen shot
422
- * Update FAQ
423
- * Added "loaded server modules" to the debug page, to better aid in support requests
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
424
 
425
  ### 4.3
426
  * Updated radio button fields
414
 
415
  Changes
416
  ===========
417
+
418
+ ### 5.0.4
419
+ * Update SSL conditional in main plugin file
420
+ * Added mcrypt module check, for API encryption
421
+ * Conditionally loaded scripts and styles in admin ( prevent conflicts )
422
+ * Included NONCE security checks on form submissions ( helps prevent CSRF and other attacks )
423
+ * Added proper update task function to add missing settings to the options page ( prevents undefined variables for new settings )
424
+ * Added missing styles to post page ( added missing icon to tinyMCE button )
425
+ * Added missing styles to widget page
426
+ * Adjusted Chimp Chatter activity time formatting to return correct time based on user time zone
427
+ * New Feature : Real time updates to Account Activity ( utilizing the heartbeat API )
428
+ * New Feature : Added account activity widget to dashboard ( with live updates using heartbeat API )
429
+ * Added screenshot of admin dashboard account activity widget
430
+
431
+ ### 5.0.3
432
+ * Re-Apply missing styles to new 'My MailChimp' Section
433
+
434
+ ### 5.0.2
435
+ * Remove extra spacing in provided short code, which caused parsing issues
436
+
437
+ ### 5.0.1
438
+ * Remove global box-sizing CSS declaration
439
+
440
+ ### 5.0
441
+ * Custom content filter to prevent other plugins from accidentally hooking in
442
+ * Updated translation files with new text and translations
443
+ * Added new screen shots
444
+ * Updated plugin activation hooks
445
+ * base64_encoded MailChimp API Key for privacy on multi-admin sites
446
+ * Added an entirely new "My MailChimp" section
447
+ * "My MailChimp" section now includes account overview details
448
+ * Added much needed campaign statistic tracking page
449
+ * Added ability to track Campaign Click/Opens with geo-data and interactive charts including world map
450
+ * Added account /listgrowth section with interactive bar chart
451
+ * Added "Chimp Chatter" feed to track account activity
452
+ * Ability to export interactive charts to png, jpg, svg
453
+ * Printable Campaign Reports
454
+ * View campaign
455
+ * Re-Branded entire Plugin
456
 
457
  ### 4.3
458
  * Updated radio button fields
readme.txt CHANGED
@@ -4,14 +4,14 @@ Donate link: http://yikesinc.com
4
  Tags: mailchimp, marketing, email, mailing lists, newsletter, signup, forms, signup form
5
  Requires at least: 3.0
6
  Tested up to: 3.9.1
7
- Stable tag: 5.0.3
8
  License: GPLv2 or later
9
 
10
- Easy MailChimp Forms allows you to easily add MailChimp signup forms to your site and track campaign stats with interactive and printable reports.
11
 
12
  == Description ==
13
 
14
- Easy MailChimp Forms allows you to easily add MailChimp signup forms to your WordPress site. You can add forms to posts, pages or sidebars with shortcodes, widgets or template tags. Simply copy and paste your MailChimp API Key into the plugin admin settings and it will pull in all your MailChimp lists. From there you can choose the lists you want to make forms for. For a single list you can check off the fields you want to include on your form and order them via an easy drag-and-drop interface. This plugin adds plenty of CSS selectors to the form code allowing you to completely customize the look of your forms. Now with the ability to track sent campaigns, you can view and print interactive reports from based on previously sent campaigns.
15
 
16
  **Note:** You will need a MailChimp API key to allow this plugin to communicate with your MailChimp account. For help on retrieving your API key, check out [question #4 of the FAQ](http://wordpress.org/plugins/yikes-inc-easy-mailchimp-extender/faq/). You can also read the MailChimp knowledge base article [Where can I find my API key and how can I use the API](http://kb.mailchimp.com/article/where-can-i-find-my-api-key/).
17
 
@@ -449,9 +449,23 @@ These functions should be used in conjunction with the `yikes_mc_get_form_data`
449
  10. Optional opt-in checkbox on the comment forms, easily add commenter's to your email list
450
  11. Custom tinyMCE button allows you to easily add imported forms to pages and posts at the click of a button
451
  12. About YIKES page
 
452
 
453
  == Changelog ==
454
 
 
 
 
 
 
 
 
 
 
 
 
 
 
455
  = 5.0.3 =
456
  * Re-Apply missing styles to new 'My MailChimp' Section
457
 
@@ -478,6 +492,7 @@ These functions should be used in conjunction with the `yikes_mc_get_form_data`
478
  * View campaign
479
  * Re-Branded entire Plugin
480
 
 
481
  = 4.4 =
482
  * Added reCAPTCHA support to prevent bots and spammers from submitting forms
483
  * Split settings page into three seperate sections
@@ -485,6 +500,7 @@ These functions should be used in conjunction with the `yikes_mc_get_form_data`
485
  * Updated translation files with new strings
486
  * Update existing screen shots and add new screen shot
487
  * Update FAQ
 
488
 
489
  = 4.3 =
490
  * Updated radio button fields
@@ -596,6 +612,19 @@ These functions should be used in conjunction with the `yikes_mc_get_form_data`
596
 
597
  == Upgrade Notice ==
598
 
 
 
 
 
 
 
 
 
 
 
 
 
 
599
  = 4.5 =
600
  * Added reCAPTCHA support to prevent bots and spammers from submitting forms
601
  * Split settings page into three seperate sections
@@ -629,13 +658,4 @@ These functions should be used in conjunction with the `yikes_mc_get_form_data`
629
  * Custom merge vars allows more customized field configuration
630
 
631
  = 1.2.0 =
632
- * First Name and Last Name fields are no longer required
633
-
634
-
635
-
636
-
637
- // To Do
638
- - Click Pie Chart visualization twice throws an error and doesn't re-draw the chart
639
- - Style arrow before chimp chatter messages
640
- - Time returned from MailChimp is wrong by 4 hours, something to do with the timezone or something
641
- - Need 4 icons ( Regular, Plain-text, A/B-split, RSS-driven )
4
  Tags: mailchimp, marketing, email, mailing lists, newsletter, signup, forms, signup form
5
  Requires at least: 3.0
6
  Tested up to: 3.9.1
7
+ Stable tag: 5.0.4
8
  License: GPLv2 or later
9
 
10
+ Easy MailChimp Forms allows you to painlessly add MailChimp signup forms to your WordPress site and track user activity with interactive reports.
11
 
12
  == Description ==
13
 
14
+ Easy MailChimp Forms allows you to painlessly add MailChimp signup forms to your WordPress site. You can add forms to posts, pages or sidebars with shortcodes, widgets or template tags. Simply copy and paste your MailChimp API Key into the plugin admin settings and it will pull in all your MailChimp lists. From there you can choose the lists you want to make forms for. For a single list you can check off the fields you want to include on your form and order them via an easy drag-and-drop interface. This plugin adds plenty of CSS selectors to the form code allowing you to completely customize the look of your forms. Now with the ability to track sent campaigns, you can view and print interactive reports from based on previously sent campaigns.
15
 
16
  **Note:** You will need a MailChimp API key to allow this plugin to communicate with your MailChimp account. For help on retrieving your API key, check out [question #4 of the FAQ](http://wordpress.org/plugins/yikes-inc-easy-mailchimp-extender/faq/). You can also read the MailChimp knowledge base article [Where can I find my API key and how can I use the API](http://kb.mailchimp.com/article/where-can-i-find-my-api-key/).
17
 
449
  10. Optional opt-in checkbox on the comment forms, easily add commenter's to your email list
450
  11. Custom tinyMCE button allows you to easily add imported forms to pages and posts at the click of a button
451
  12. About YIKES page
452
+ 13. *New* Admin Dashboard Widget - Account Activity ( With Live Updating )
453
 
454
  == Changelog ==
455
 
456
+ = 5.0.4 =
457
+ * Update SSL conditional in main plugin file
458
+ * Added mcrypt module check, for API encryption
459
+ * Conditionally loaded scripts and styles in admin ( prevent conflicts )
460
+ * Included NONCE security checks on form submissions ( helps prevent CSRF and other attacks )
461
+ * Added proper update task function to add missing settings to the options page ( prevents undefined variables for new settings )
462
+ * Added missing styles to post page ( added missing icon to tinyMCE button )
463
+ * Added missing styles to widget page
464
+ * Adjusted Chimp Chatter activity time formatting to return correct time based on user time zone
465
+ * New Feature : Real time updates to Account Activity ( utilizing the heartbeat API )
466
+ * New Feature : Added account activity widget to dashboard ( with live updates using heartbeat API )
467
+ * Added screenshot of admin dashboard account activity widget
468
+
469
  = 5.0.3 =
470
  * Re-Apply missing styles to new 'My MailChimp' Section
471
 
492
  * View campaign
493
  * Re-Branded entire Plugin
494
 
495
+
496
  = 4.4 =
497
  * Added reCAPTCHA support to prevent bots and spammers from submitting forms
498
  * Split settings page into three seperate sections
500
  * Updated translation files with new strings
501
  * Update existing screen shots and add new screen shot
502
  * Update FAQ
503
+ * Added "loaded server modules" to the debug page, to better aid in support requests
504
 
505
  = 4.3 =
506
  * Updated radio button fields
612
 
613
  == Upgrade Notice ==
614
 
615
+ = 5.0.4 =
616
+ * Update SSL conditional in main plugin file
617
+ * Added mcrypt module check, for API encryption
618
+ * Conditionally loaded scripts and styles in admin ( prevent conflicts )
619
+ * Included NONCE security checks on form submissions ( helps prevent CSRF and other attacks )
620
+ * Added proper update task function to add missing settings to the options page ( prevents undefined variables for new settings )
621
+ * Added missing styles to post page ( added missing icon to tinyMCE button )
622
+ * Added missing styles to widget page
623
+ * Adjusted Chimp Chatter activity time formatting to return correct time based on user time zone
624
+ * New Feature : Real time updates to Account Activity ( utilizing the heartbeat API )
625
+ * New Feature : Added account activity widget to dashboard ( with live updates using heartbeat API )
626
+ * Added screenshot of admin dashboard account activity widget
627
+
628
  = 4.5 =
629
  * Added reCAPTCHA support to prevent bots and spammers from submitting forms
630
  * Split settings page into three seperate sections
658
  * Custom merge vars allows more customized field configuration
659
 
660
  = 1.2.0 =
661
+ * First Name and Last Name fields are no longer required
 
 
 
 
 
 
 
 
 
templates/mailChimp-account-overview.php CHANGED
@@ -1,91 +1,91 @@
1
- <?php
2
-
3
- // create and store our account detail variables
4
- $current_date = date('Y-m-d' /* testing future date, strtotime("+30 days") */ );
5
-
6
- // Username
7
- $account_username = $account_details['username'];
8
- // Member Since
9
- $member_since_explosion = explode( ' ' , $account_details['member_since'] );
10
- $member_since_date = date( 'm/d/Y' , strtotime($member_since_explosion[0]) );
11
-
12
- // when emails will reset
13
- $email_reset_date = date('m/d/Y', strtotime($member_since_date. ' + 30 days'));
14
-
15
- // loop over to figure out when our reset date will be
16
- // happens every 30 days!
17
- if ( strtotime($current_date) > strtotime($email_reset_date) ) {
18
- while ( strtotime($current_date) > strtotime($email_reset_date) ) {
19
- $email_reset_date = date('m/d/Y', strtotime($email_reset_date. ' + 30 days'));
20
- }
21
- }
22
-
23
- // Is Account Activated
24
- $is_activated = $account_details['has_activated'];
25
-
26
- // Industry
27
- $industry = $account_details['industry'];
28
-
29
- // plan type
30
- $plan_type = $account_details['plan_type'];
31
- if ( $plan_type = 'free' ) {
32
- $plan_type = __( 'Free Forever', 'yikes-inc-easy-mailchimp-extender');
33
- // if the user is a free user,
34
- // store the number of emails left
35
- $emails_left = $account_details['emails_left'];
36
- } elseif ( $plan_type = 'payasyougo' ) {
37
- $plan_type = __( 'Pay As You Go', 'yikes-inc-easy-mailchimp-extender');
38
- // if the user is a free user,
39
- // store the number of emails left
40
- $emails_left = $account_details['emails_left'];
41
- } else {
42
- $plan_type = __( 'Premium Chimp', 'yikes-inc-easy-mailchimp-extender');
43
- }
44
-
45
- // set the styles for the activated indicator div
46
- if ( $is_activated == '1' ) {
47
- $activated_id = 'yks-mc-account-activated';
48
- } else {
49
- $activated_id = 'yks-mc-account-not-activated';
50
- }
51
-
52
- ?>
53
-
54
- <style>
55
- span.profile_info_span {
56
- display:block;
57
- float:left;
58
- margin: 2.5em;
59
- width:10%;
60
- }
61
- span.profile_info_span:first-child {
62
- margin: 2.5em 2.5em 2.5em 0 !important;
63
- }
64
- </style>
65
-
66
- <div class="wrap">
67
-
68
- <div id="is_account_active" style="float:right;text-align:center;">
69
- <div id="<?php echo $activated_id; ?>"></div>
70
- <span style="float:right;"><?php if ( $is_activated == 0 ) { _e( 'Account Not Yet Activated', 'yikes-inc-easy-mailchimp-extender'); } else { _e( 'Account Active', 'yikes-inc-easy-mailchimp-extender'); } ?></span>
71
- </div>
72
-
73
- <span class="profile_info_span"><h3><?php _e( 'Company', 'yikes-inc-easy-mailchimp-extender'); ?> : </h3><?php echo $account_username; ?></span>
74
- <span class="profile_info_span"><h3><?php _e( 'Member Since', 'yikes-inc-easy-mailchimp-extender'); ?> : </h3><?php echo $member_since_date; ?></span>
75
-
76
- <span class="profile_info_span"><h3><?php _e( 'Account Type', 'yikes-inc-easy-mailchimp-extender'); ?> : </h3><?php echo $plan_type; ?></span>
77
-
78
- <?php
79
- if ( $plan_type == __( 'Free Forever', 'yikes-inc-easy-mailchimp-extender') || $plan_type == __( 'Pay As You Go', 'yikes-inc-easy-mailchimp-extender') ) {
80
- ?>
81
- <div id="yks-mc-emails-left">
82
- <span class="profile_info_span"><h3><?php _e( 'Emails Left', 'yikes-inc-easy-mailchimp-extender'); ?> : </h3><?php echo number_format ($emails_left); ?></span>
83
- <span class="profile_info_span"><h3><?php _e( 'Emails will reset on', 'yikes-inc-easy-mailchimp-extender'); ?> </h3><em><?php echo $email_reset_date; ?></em></span>
84
- </div>
85
- <?php
86
- }
87
- ?>
88
-
89
- <span class="profile_info_span"><h3><?php _e( 'Industry', 'yikes-inc-easy-mailchimp-extender'); ?> : </h3><?php if ( $industry != '' ) { echo $industry; } else { echo '<em>n/a</em>'; } ?></span>
90
-
91
  </div>
1
+ <?php
2
+
3
+ // create and store our account detail variables
4
+ $current_date = date('Y-m-d' /* testing future date, strtotime("+30 days") */ );
5
+
6
+ // Username
7
+ $account_username = $account_details['username'];
8
+ // Member Since
9
+ $member_since_explosion = explode( ' ' , $account_details['member_since'] );
10
+ $member_since_date = date( 'm/d/Y' , strtotime($member_since_explosion[0]) );
11
+
12
+ // when emails will reset
13
+ $email_reset_date = date('m/d/Y', strtotime($member_since_date. ' + 30 days'));
14
+
15
+ // loop over to figure out when our reset date will be
16
+ // happens every 30 days!
17
+ if ( strtotime($current_date) > strtotime($email_reset_date) ) {
18
+ while ( strtotime($current_date) > strtotime($email_reset_date) ) {
19
+ $email_reset_date = date('m/d/Y', strtotime($email_reset_date. ' + 30 days'));
20
+ }
21
+ }
22
+
23
+ // Is Account Activated
24
+ $is_activated = $account_details['has_activated'];
25
+
26
+ // Industry
27
+ $industry = $account_details['industry'];
28
+
29
+ // plan type
30
+ $plan_type = $account_details['plan_type'];
31
+ if ( $plan_type = 'free' ) {
32
+ $plan_type = __( 'Free Forever', 'yikes-inc-easy-mailchimp-extender');
33
+ // if the user is a free user,
34
+ // store the number of emails left
35
+ $emails_left = $account_details['emails_left'];
36
+ } elseif ( $plan_type = 'payasyougo' ) {
37
+ $plan_type = __( 'Pay As You Go', 'yikes-inc-easy-mailchimp-extender');
38
+ // if the user is a free user,
39
+ // store the number of emails left
40
+ $emails_left = $account_details['emails_left'];
41
+ } else {
42
+ $plan_type = __( 'Premium Chimp', 'yikes-inc-easy-mailchimp-extender');
43
+ }
44
+
45
+ // set the styles for the activated indicator div
46
+ if ( $is_activated == '1' ) {
47
+ $activated_id = 'yks-mc-account-activated';
48
+ } else {
49
+ $activated_id = 'yks-mc-account-not-activated';
50
+ }
51
+
52
+ ?>
53
+
54
+ <style>
55
+ span.profile_info_span {
56
+ display:block;
57
+ float:left;
58
+ margin: 2.5em;
59
+ width:10%;
60
+ }
61
+ span.profile_info_span:first-child {
62
+ margin: 2.5em 2.5em 2.5em 0 !important;
63
+ }
64
+ </style>
65
+
66
+ <div class="wrap">
67
+
68
+ <div id="is_account_active" style="float:right;text-align:center;">
69
+ <div id="<?php echo $activated_id; ?>"></div>
70
+ <span style="float:right;"><?php if ( $is_activated == 0 ) { _e( 'Account Not Yet Activated', 'yikes-inc-easy-mailchimp-extender'); } else { _e( 'Account Active', 'yikes-inc-easy-mailchimp-extender'); } ?></span>
71
+ </div>
72
+
73
+ <span class="profile_info_span"><h3><?php _e( 'Company', 'yikes-inc-easy-mailchimp-extender'); ?> : </h3><?php echo $account_username; ?></span>
74
+ <span class="profile_info_span"><h3><?php _e( 'Member Since', 'yikes-inc-easy-mailchimp-extender'); ?> : </h3><?php echo $member_since_date; ?></span>
75
+
76
+ <span class="profile_info_span"><h3><?php _e( 'Account Type', 'yikes-inc-easy-mailchimp-extender'); ?> : </h3><?php echo $plan_type; ?></span>
77
+
78
+ <?php
79
+ if ( $plan_type == __( 'Free Forever', 'yikes-inc-easy-mailchimp-extender') || $plan_type == __( 'Pay As You Go', 'yikes-inc-easy-mailchimp-extender') ) {
80
+ ?>
81
+ <div id="yks-mc-emails-left">
82
+ <span class="profile_info_span"><h3><?php _e( 'Emails Left', 'yikes-inc-easy-mailchimp-extender'); ?> : </h3><?php echo number_format ($emails_left); ?></span>
83
+ <span class="profile_info_span"><h3><?php _e( 'Emails will reset on', 'yikes-inc-easy-mailchimp-extender'); ?> </h3><em><?php echo $email_reset_date; ?></em></span>
84
+ </div>
85
+ <?php
86
+ }
87
+ ?>
88
+
89
+ <span class="profile_info_span"><h3><?php _e( 'Industry', 'yikes-inc-easy-mailchimp-extender'); ?> : </h3><?php if ( $industry != '' ) { echo $industry; } else { echo '<em>n/a</em>'; } ?></span>
90
+
91
  </div>
templates/mailChimp-campaign-click-geo-map.php CHANGED
@@ -1,159 +1,159 @@
1
- <?php
2
-
3
- // geo data array
4
- // of cities and values
5
- $geo_data_array = array();
6
-
7
- // build our array of geo data
8
- // to use to populate our SVG map
9
- foreach ( $resp as $geo_data ) {
10
- // push to our geo data list
11
- array_push( $geo_data_array , '{ "value" : ' . $geo_data['opens'] . ', "code" : ' . '"' . $geo_data['code'] . '" } ,' );
12
- }
13
-
14
- // sorting function
15
- // for top 5 countries
16
- function cmp($a, $b) {
17
- return $a["opens"] - $b["opens"];
18
- }
19
-
20
- // sort our opened data
21
- usort( $resp , "cmp" );
22
-
23
- // empty list data array
24
- $list_data_array = array();
25
- $i = 0;
26
- // populate our list data array
27
- foreach ( $resp as $data ) {
28
- $list_data_array[$i]['country'] = $data['code'];
29
- $list_data_array[$i]['opens'] = $data['opens'];
30
- // check if the name is set,
31
- // if its not we'll use the first region name
32
- // this happens in Great Britain (England)
33
- if ( isset ( $data['name'] ) ) {
34
- $list_data_array[$i]['name'] = $data['name'];
35
- } else {
36
- $list_data_array[$i]['name'] = $data['regions'][0]['name'];
37
- }
38
- $i++;
39
- }
40
-
41
- $reversed_data_array = array_reverse( $list_data_array );
42
-
43
- // print_r($resp);
44
-
45
- // print_r($geo_data_array_encode);
46
-
47
- ?>
48
-
49
- <!-- Flag sprites service provided by Martijn Lafeber, https://github.com/lafeber/world-flags-sprite/blob/master/LICENSE -->
50
- <link rel="stylesheet" type="text/css" href="http://cloud.github.com/downloads/lafeber/world-flags-sprite/flags32.css" />
51
-
52
- <style type="text/css">
53
- #geo_map {
54
- height: 500px;
55
- min-width: 310px;
56
- max-width: 100%;
57
- margin: 0 auto;
58
- }
59
- .loading {
60
- margin-top: 10em;
61
- text-align: center;
62
- color: gray;
63
- }
64
- </style>
65
- <script type="text/javascript">
66
- jQuery(function () {
67
-
68
- jQuery.getJSON('http://www.highcharts.com/samples/data/jsonp.php?filename=world-population-density.json&callback=?', function (data) {
69
-
70
-
71
- // Initiate the geo map
72
- jQuery('#geo_map').highcharts('Map', {
73
-
74
- title : {
75
- text : 'Campaign Opens Around The World'
76
- },
77
-
78
- mapNavigation: {
79
- enabled: true,
80
- buttonOptions: {
81
- verticalAlign: 'bottom'
82
- }
83
- },
84
-
85
- colorAxis: {
86
- min: 1,
87
- max: 1000,
88
- type: 'logarithmic'
89
- },
90
-
91
- series : [{
92
- data : [
93
- <?php echo implode( ' ' , $geo_data_array ); ?>
94
- ],
95
- mapData: Highcharts.maps['custom/world'],
96
- joinBy: ['iso-a2', 'code'],
97
- name: '<?php __( 'Number of Campaign Opens' , 'yikes-inc-easy-mailchimp-extender' ); ?>',
98
- states: {
99
- hover: {
100
- color: '#BADA55'
101
- }
102
- },
103
- tooltip: {
104
- valueSuffix: ' opens'
105
- },
106
-
107
- }],
108
- credits: {
109
- enabled: false
110
- },
111
- });
112
- });
113
- });
114
- </script>
115
-
116
-
117
- <section class="overview_information_section">
118
-
119
- <div class="overview_information">
120
-
121
- <h2><?php _e('Campaign Activity Geo Map', 'yikes-inc-easy-mailchimp-extender'); ?></h2>
122
-
123
- <div id="geo_map" style="max-width: 100%;min-width: 100%;"></div>
124
-
125
- <div id="geo_data_top_clicks">
126
-
127
- <h3><?php _e('Top Opens By Country', 'yikes-inc-easy-mailchimp-extender'); ?> : </h3>
128
-
129
- <table id="yks-admin-link-data-table">
130
- <tbody>
131
- <!-- header -->
132
- <tr>
133
- <td class="link_data_table_head"><strong><?php _e('Country', 'yikes-inc-easy-mailchimp-extender'); ?></strong></td>
134
- <td class="link_data_table_head"><strong><?php _e('Opens', 'yikes-inc-easy-mailchimp-extender'); ?></strong></td>
135
- </tr>
136
-
137
- <?php
138
- $limit = 0;
139
- foreach ($reversed_data_array as $list_data) {
140
- echo '<tr class="f32">';
141
- // limit the number of returned countries
142
- // to 5. Break when the limit hits 6
143
- if ( $limit == 5 ) {
144
- break;
145
- } else {
146
- echo '<td><li class="flag '.strtolower($list_data["country"]).'"></li> '.$list_data['name'].'</td>';
147
- echo '<td>'.$list_data['opens'].'</td>';
148
- }
149
- $limit++;
150
- echo '</tr>';
151
- }
152
- ?>
153
-
154
- </div>
155
-
156
-
157
- </div>
158
-
159
  </section>
1
+ <?php
2
+
3
+ // geo data array
4
+ // of cities and values
5
+ $geo_data_array = array();
6
+
7
+ // build our array of geo data
8
+ // to use to populate our SVG map
9
+ foreach ( $resp as $geo_data ) {
10
+ // push to our geo data list
11
+ array_push( $geo_data_array , '{ "value" : ' . $geo_data['opens'] . ', "code" : ' . '"' . $geo_data['code'] . '" } ,' );
12
+ }
13
+
14
+ // sorting function
15
+ // for top 5 countries
16
+ function cmp($a, $b) {
17
+ return $a["opens"] - $b["opens"];
18
+ }
19
+
20
+ // sort our opened data
21
+ usort( $resp , "cmp" );
22
+
23
+ // empty list data array
24
+ $list_data_array = array();
25
+ $i = 0;
26
+ // populate our list data array
27
+ foreach ( $resp as $data ) {
28
+ $list_data_array[$i]['country'] = $data['code'];
29
+ $list_data_array[$i]['opens'] = $data['opens'];
30
+ // check if the name is set,
31
+ // if its not we'll use the first region name
32
+ // this happens in Great Britain (England)
33
+ if ( isset ( $data['name'] ) ) {
34
+ $list_data_array[$i]['name'] = $data['name'];
35
+ } else {
36
+ $list_data_array[$i]['name'] = $data['regions'][0]['name'];
37
+ }
38
+ $i++;
39
+ }
40
+
41
+ $reversed_data_array = array_reverse( $list_data_array );
42
+
43
+ // print_r($resp);
44
+
45
+ // print_r($geo_data_array_encode);
46
+
47
+ ?>
48
+
49
+ <!-- Flag sprites service provided by Martijn Lafeber, https://github.com/lafeber/world-flags-sprite/blob/master/LICENSE -->
50
+ <link rel="stylesheet" type="text/css" href="http://cloud.github.com/downloads/lafeber/world-flags-sprite/flags32.css" />
51
+
52
+ <style type="text/css">
53
+ #geo_map {
54
+ height: 500px;
55
+ min-width: 310px;
56
+ max-width: 100%;
57
+ margin: 0 auto;
58
+ }
59
+ .loading {
60
+ margin-top: 10em;
61
+ text-align: center;
62
+ color: gray;
63
+ }
64
+ </style>
65
+ <script type="text/javascript">
66
+ jQuery(function () {
67
+
68
+ jQuery.getJSON('http://www.highcharts.com/samples/data/jsonp.php?filename=world-population-density.json&callback=?', function (data) {
69
+
70
+
71
+ // Initiate the geo map
72
+ jQuery('#geo_map').highcharts('Map', {
73
+
74
+ title : {
75
+ text : 'Campaign Opens Around The World'
76
+ },
77
+
78
+ mapNavigation: {
79
+ enabled: true,
80
+ buttonOptions: {
81
+ verticalAlign: 'bottom'
82
+ }
83
+ },
84
+
85
+ colorAxis: {
86
+ min: 1,
87
+ max: 1000,
88
+ type: 'logarithmic'
89
+ },
90
+
91
+ series : [{
92
+ data : [
93
+ <?php echo implode( ' ' , $geo_data_array ); ?>
94
+ ],
95
+ mapData: Highcharts.maps['custom/world'],
96
+ joinBy: ['iso-a2', 'code'],
97
+ name: '<?php __( 'Number of Campaign Opens' , 'yikes-inc-easy-mailchimp-extender' ); ?>',
98
+ states: {
99
+ hover: {
100
+ color: '#BADA55'
101
+ }
102
+ },
103
+ tooltip: {
104
+ valueSuffix: ' opens'
105
+ },
106
+
107
+ }],
108
+ credits: {
109
+ enabled: false
110
+ },
111
+ });
112
+ });
113
+ });
114
+ </script>
115
+
116
+
117
+ <section class="overview_information_section">
118
+
119
+ <div class="overview_information">
120
+
121
+ <h2><?php _e('Campaign Activity Geo Map', 'yikes-inc-easy-mailchimp-extender'); ?></h2>
122
+
123
+ <div id="geo_map" style="max-width: 100%;min-width: 100%;"></div>
124
+
125
+ <div id="geo_data_top_clicks">
126
+
127
+ <h3><?php _e('Top Opens By Country', 'yikes-inc-easy-mailchimp-extender'); ?> : </h3>
128
+
129
+ <table id="yks-admin-link-data-table">
130
+ <tbody>
131
+ <!-- header -->
132
+ <tr>
133
+ <td class="link_data_table_head"><strong><?php _e('Country', 'yikes-inc-easy-mailchimp-extender'); ?></strong></td>
134
+ <td class="link_data_table_head"><strong><?php _e('Opens', 'yikes-inc-easy-mailchimp-extender'); ?></strong></td>
135
+ </tr>
136
+
137
+ <?php
138
+ $limit = 0;
139
+ foreach ($reversed_data_array as $list_data) {
140
+ echo '<tr class="f32">';
141
+ // limit the number of returned countries
142
+ // to 5. Break when the limit hits 6
143
+ if ( $limit == 5 ) {
144
+ break;
145
+ } else {
146
+ echo '<td><li class="flag '.strtolower($list_data["country"]).'"></li> '.$list_data['name'].'</td>';
147
+ echo '<td>'.$list_data['opens'].'</td>';
148
+ }
149
+ $limit++;
150
+ echo '</tr>';
151
+ }
152
+ ?>
153
+
154
+ </div>
155
+
156
+
157
+ </div>
158
+
159
  </section>
templates/mailChimp-campaign-click-report.php CHANGED
@@ -1,178 +1,178 @@
1
- <?php
2
- // get our data from the MailChimp API Response
3
- $click_report_data = $campaign_click_stats;
4
-
5
- // Load Thickbox
6
- add_thickbox();
7
-
8
- ?>
9
-
10
- <style>
11
- .green-flat-button {
12
- position: relative;
13
- vertical-align: top;
14
- width: 200px;
15
- height: 45px;
16
- padding: 0;
17
- font-size: 16px;
18
- color: white;
19
- text-align: center;
20
- text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
21
- background: #27ae60;
22
- border: 0;
23
- border-bottom: 2px solid #219d55;
24
- cursor: pointer;
25
- -webkit-box-shadow: inset 0 -2px #219d55;
26
- box-shadow: inset 0 -2px #219d55;
27
- }
28
- .green-flat-button:active {
29
- top: 1px;
30
- outline: none;
31
- -webkit-box-shadow: none;
32
- box-shadow: none;
33
- }
34
- #TB_window, #TB_ajaxContent {
35
- min-width: 60% !important;
36
- }
37
-
38
- #TB_ajaxContent {
39
- display:block !important;
40
- margin:0 auto !important;
41
- width:100% !important;
42
- }
43
- </style>
44
-
45
-
46
-
47
- <div id="click-data">
48
-
49
- <table id="yks-admin-link-data-table">
50
- <tbody>
51
-
52
- <?php
53
-
54
- echo '<h2>Specific Link Data</h2>';
55
-
56
- // if the report data is not empty, display our clicked link data chart
57
- if ( !empty($click_report_data['total']) ) {
58
- ?>
59
- <a href="#" onclick="return false;" class=""><input class="green-flat-button view_clicks_as_piechart yks-mc-no-print" type="button" value="<?php _e( 'Visualize Me' , 'yikes-inc-easy-mailchimp-extender' ); ?>" /></a>
60
-
61
- <tr>
62
- <td class="link_data_table_head"><strong><?php _e( 'URL' , 'yikes-inc-easy-mailchimp-extender' ); ?></strong></td>
63
- <td class="link_data_table_head"><strong><?php _e( 'Clicks' , 'yikes-inc-easy-mailchimp-extender' ); ?></strong></td>
64
- <td class="link_data_table_head"><strong><?php _e( 'Click Percent' , 'yikes-inc-easy-mailchimp-extender' ); ?></strong></td>
65
- <td class="link_data_table_head"><strong><?php _e( 'Unique Clicks' , 'yikes-inc-easy-mailchimp-extender' ); ?></strong></td>
66
- <td class="link_data_table_head"><strong><?php _e( 'Unique Percent' , 'yikes-inc-easy-mailchimp-extender' ); ?></strong></td>
67
- </tr>
68
- <?php
69
- } else {
70
- ?>
71
- <a href="#" onclick="return false;" class="" style="float:right;"><input disabled="disabled" class="green-flat-button yks-mc-no-print" type="button" value="<?php _e( 'Visualize Me' , 'yikes-inc-easy-mailchimp-extender' ); ?>" /></a>
72
-
73
- <tr style="opacity:.25;">
74
- <td class="link_data_table_head"><strong><?php _e( 'URL' , 'yikes-inc-easy-mailchimp-extender' ); ?></strong></td>
75
- <td class="link_data_table_head"><strong><?php _e( 'Clicks' , 'yikes-inc-easy-mailchimp-extender' ); ?></strong></td>
76
- <td class="link_data_table_head"><strong><?php _e( 'Click Percent' , 'yikes-inc-easy-mailchimp-extender' ); ?></strong></td>
77
- <td class="link_data_table_head"><strong><?php _e( 'Unique Clicks' , 'yikes-inc-easy-mailchimp-extender' ); ?></strong></td>
78
- <td class="link_data_table_head"><strong><?php _e( 'Unique Percent' , 'yikes-inc-easy-mailchimp-extender' ); ?></strong></td>
79
- </tr>
80
-
81
- <tr><td class="yks-mc-report-error" style="position:absolute;width:98%;"><?php _e( 'No Links Clicked' , 'yikes-inc-easy-mailchimp-extender' ); ?></td></tr>
82
-
83
- <!-- add da top margin to our geo map to make room for the no clicked links error -->
84
- <style>
85
- #geo_data_link_map {
86
- display:block;
87
- margin-top:4em !important;
88
- }
89
- </style>
90
- <?php
91
- }
92
-
93
- // print_r($click_report_data);
94
-
95
- $links_array = array();
96
- $percentage_array = array();
97
-
98
- /** Test **/
99
- $data_array = array();
100
-
101
- foreach ( $click_report_data['total'] as $data ) {
102
- // set variables
103
- // explode the url, to clean it of any MalChimp tracking data
104
- $explode_url = explode( '?utm_source' , $data['url'] );
105
- // store the cleaned URL
106
- $data_clean_url = $explode_url[0];
107
- $url_clicks = $data['clicks'];
108
- $url_clicks_percent = round((float)$data['clicks_percent'] * 100 ) . '%';
109
- $url_unique = $data['unique'];
110
- $url_unique_percent = round((float)$data['unique_percent'] * 100 ) . '%';
111
-
112
- // array_push( $links_array , $data_clean_url );
113
- // array_push( $percentage_array , $url_clicks_percent );
114
-
115
- array_push( $data_array , $data_clean_url.'-----'.$url_clicks_percent );
116
-
117
-
118
- echo '<tr><td>&nbsp;</td></tr>';
119
- echo '<tr>';
120
- echo '<td class="single_click_item first"><a href="' . $data_clean_url .'" target="_blank">' . $data_clean_url . '</a></td>';
121
- echo '<td class="single_click_item">' . $url_clicks . '</td>';
122
- echo '<td class="single_click_item">' . $url_clicks_percent . '</td>';
123
- echo '<td class="single_click_item">' . $url_unique . '</td>';
124
- echo '<td class="single_click_item last">' . $url_unique_percent . '</td>';
125
- echo '</tr>';
126
- echo '<tr><td>&nbsp;</td></tr>';
127
- }
128
- ?>
129
-
130
- </tbody>
131
- </table>
132
-
133
- <div id="click_data_pie_chart" style="width:950px; display:none;">
134
- <img class="mailChimp_get_subscribers_preloader" src="<?php echo admin_url().'/images/wpspin_light.gif'; ?>" alt="preloader" >
135
- </div>
136
-
137
- </div>
138
-
139
- <!-- javascript , ajax etc. -->
140
- <script type="text/javascript">
141
- jQuery(function () {
142
-
143
- // Ajax request to send our data away
144
- // to be returned and rendered in a Pie Chart
145
- jQuery('.view_clicks_as_piechart').on( 'click' , function() {
146
-
147
- tb_show('Link Click Percentage - Pie Chart', '?type=extended&width=800&height=600');
148
-
149
- setTimeout(function() {
150
-
151
- jQuery.ajax({
152
- type: 'POST',
153
- url: ajaxurl,
154
- data: {
155
- action: 'yks_mailchimp_form',
156
- form_action: 'yks_get_piechart',
157
- pie_chart_data_array: '<?php echo json_encode($data_array); ?>'
158
- },
159
- dataType: 'html',
160
- success: function(response) {
161
-
162
- // reload the chart
163
- jQuery('#TB_ajaxContent').html(response).css('opacity',0).animate({
164
- opacity: 1
165
- }, 800);
166
-
167
- },
168
- error: function (error_response) {
169
- alert(error_response);
170
- }
171
- });
172
-
173
- }, 350);
174
-
175
- });
176
-
177
- });
178
  </script>
1
+ <?php
2
+ // get our data from the MailChimp API Response
3
+ $click_report_data = $campaign_click_stats;
4
+
5
+ // Load Thickbox
6
+ add_thickbox();
7
+
8
+ ?>
9
+
10
+ <style>
11
+ .green-flat-button {
12
+ position: relative;
13
+ vertical-align: top;
14
+ width: 200px;
15
+ height: 45px;
16
+ padding: 0;
17
+ font-size: 16px;
18
+ color: white;
19
+ text-align: center;
20
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
21
+ background: #27ae60;
22
+ border: 0;
23
+ border-bottom: 2px solid #219d55;
24
+ cursor: pointer;
25
+ -webkit-box-shadow: inset 0 -2px #219d55;
26
+ box-shadow: inset 0 -2px #219d55;
27
+ }
28
+ .green-flat-button:active {
29
+ top: 1px;
30
+ outline: none;
31
+ -webkit-box-shadow: none;
32
+ box-shadow: none;
33
+ }
34
+ #TB_window, #TB_ajaxContent {
35
+ min-width: 60% !important;
36
+ }
37
+
38
+ #TB_ajaxContent {
39
+ display:block !important;
40
+ margin:0 auto !important;
41
+ width:100% !important;
42
+ }
43
+ </style>
44
+
45
+
46
+
47
+ <div id="click-data">
48
+
49
+ <table id="yks-admin-link-data-table">
50
+ <tbody>
51
+
52
+ <?php
53
+
54
+ echo '<h2>Specific Link Data</h2>';
55
+
56
+ // if the report data is not empty, display our clicked link data chart
57
+ if ( !empty($click_report_data['total']) ) {
58
+ ?>
59
+ <a href="#" onclick="return false;" class=""><input class="green-flat-button view_clicks_as_piechart yks-mc-no-print" type="button" value="<?php _e( 'Visualize Me' , 'yikes-inc-easy-mailchimp-extender' ); ?>" /></a>
60
+
61
+ <tr>
62
+ <td class="link_data_table_head"><strong><?php _e( 'URL' , 'yikes-inc-easy-mailchimp-extender' ); ?></strong></td>
63
+ <td class="link_data_table_head"><strong><?php _e( 'Clicks' , 'yikes-inc-easy-mailchimp-extender' ); ?></strong></td>
64
+ <td class="link_data_table_head"><strong><?php _e( 'Click Percent' , 'yikes-inc-easy-mailchimp-extender' ); ?></strong></td>
65
+ <td class="link_data_table_head"><strong><?php _e( 'Unique Clicks' , 'yikes-inc-easy-mailchimp-extender' ); ?></strong></td>
66
+ <td class="link_data_table_head"><strong><?php _e( 'Unique Percent' , 'yikes-inc-easy-mailchimp-extender' ); ?></strong></td>
67
+ </tr>
68
+ <?php
69
+ } else {
70
+ ?>
71
+ <a href="#" onclick="return false;" class="" style="float:right;"><input disabled="disabled" class="green-flat-button yks-mc-no-print" type="button" value="<?php _e( 'Visualize Me' , 'yikes-inc-easy-mailchimp-extender' ); ?>" /></a>
72
+
73
+ <tr style="opacity:.25;">
74
+ <td class="link_data_table_head"><strong><?php _e( 'URL' , 'yikes-inc-easy-mailchimp-extender' ); ?></strong></td>
75
+ <td class="link_data_table_head"><strong><?php _e( 'Clicks' , 'yikes-inc-easy-mailchimp-extender' ); ?></strong></td>
76
+ <td class="link_data_table_head"><strong><?php _e( 'Click Percent' , 'yikes-inc-easy-mailchimp-extender' ); ?></strong></td>
77
+ <td class="link_data_table_head"><strong><?php _e( 'Unique Clicks' , 'yikes-inc-easy-mailchimp-extender' ); ?></strong></td>
78
+ <td class="link_data_table_head"><strong><?php _e( 'Unique Percent' , 'yikes-inc-easy-mailchimp-extender' ); ?></strong></td>
79
+ </tr>
80
+
81
+ <tr><td class="yks-mc-report-error" style="position:absolute;width:98%;"><?php _e( 'No Links Clicked' , 'yikes-inc-easy-mailchimp-extender' ); ?></td></tr>
82
+
83
+ <!-- add da top margin to our geo map to make room for the no clicked links error -->
84
+ <style>
85
+ #geo_data_link_map {
86
+ display:block;
87
+ margin-top:4em !important;
88
+ }
89
+ </style>
90
+ <?php
91
+ }
92
+
93
+ // print_r($click_report_data);
94
+
95
+ $links_array = array();
96
+ $percentage_array = array();
97
+
98
+ /** Test **/
99
+ $data_array = array();
100
+
101
+ foreach ( $click_report_data['total'] as $data ) {
102
+ // set variables
103
+ // explode the url, to clean it of any MalChimp tracking data
104
+ $explode_url = explode( '?utm_source' , $data['url'] );
105
+ // store the cleaned URL
106
+ $data_clean_url = $explode_url[0];
107
+ $url_clicks = $data['clicks'];
108
+ $url_clicks_percent = round((float)$data['clicks_percent'] * 100 ) . '%';
109
+ $url_unique = $data['unique'];
110
+ $url_unique_percent = round((float)$data['unique_percent'] * 100 ) . '%';
111
+
112
+ // array_push( $links_array , $data_clean_url );
113
+ // array_push( $percentage_array , $url_clicks_percent );
114
+
115
+ array_push( $data_array , $data_clean_url.'-----'.$url_clicks_percent );
116
+
117
+
118
+ echo '<tr><td>&nbsp;</td></tr>';
119
+ echo '<tr>';
120
+ echo '<td class="single_click_item first"><a href="' . $data_clean_url .'" target="_blank">' . $data_clean_url . '</a></td>';
121
+ echo '<td class="single_click_item">' . $url_clicks . '</td>';
122
+ echo '<td class="single_click_item">' . $url_clicks_percent . '</td>';
123
+ echo '<td class="single_click_item">' . $url_unique . '</td>';
124
+ echo '<td class="single_click_item last">' . $url_unique_percent . '</td>';
125
+ echo '</tr>';
126
+ echo '<tr><td>&nbsp;</td></tr>';
127
+ }
128
+ ?>
129
+
130
+ </tbody>
131
+ </table>
132
+
133
+ <div id="click_data_pie_chart" style="width:950px; display:none;">
134
+ <img class="mailChimp_get_subscribers_preloader" src="<?php echo admin_url().'/images/wpspin_light.gif'; ?>" alt="preloader" >
135
+ </div>
136
+
137
+ </div>
138
+
139
+ <!-- javascript , ajax etc. -->
140
+ <script type="text/javascript">
141
+ jQuery(function () {
142
+
143
+ // Ajax request to send our data away
144
+ // to be returned and rendered in a Pie Chart
145
+ jQuery('.view_clicks_as_piechart').on( 'click' , function() {
146
+
147
+ tb_show('Link Click Percentage - Pie Chart', '?type=extended&width=800&height=600');
148
+
149
+ setTimeout(function() {
150
+
151
+ jQuery.ajax({
152
+ type: 'POST',
153
+ url: ajaxurl,
154
+ data: {
155
+ action: 'yks_mailchimp_form',
156
+ form_action: 'yks_get_piechart',
157
+ pie_chart_data_array: '<?php echo json_encode($data_array); ?>'
158
+ },
159
+ dataType: 'html',
160
+ success: function(response) {
161
+
162
+ // reload the chart
163
+ jQuery('#TB_ajaxContent').html(response).css('opacity',0).animate({
164
+ opacity: 1
165
+ }, 800);
166
+
167
+ },
168
+ error: function (error_response) {
169
+ alert(error_response);
170
+ }
171
+ });
172
+
173
+ }, 350);
174
+
175
+ });
176
+
177
+ });
178
  </script>
templates/mailChimp-campaign-clicks-pie-chart.php CHANGED
@@ -1,97 +1,97 @@
1
- <?php
2
-
3
- $pie_chart_data = json_decode(stripslashes($pie_chart_link_data_array));
4
-
5
- $the_pie_chart_data_array = array();
6
-
7
- foreach ( $pie_chart_data as $chart_data ) {
8
- $chart_data_explosion = explode( '-----' , $chart_data );
9
- $chart_data_link = $chart_data_explosion[0];
10
- $chart_data_percent = $chart_data_explosion[1];
11
-
12
- array_push( $the_pie_chart_data_array , " ' " . $chart_data_link . " ' , " . str_replace( '%' , '' , $chart_data_percent) );
13
- }
14
-
15
- echo '<h2 style="width:100%;text-align:center;">' . __( "Link Click Percentage - Pie Chart" , "yikes-inc-easy-mailchimp-extender" ) . '</h2>';
16
-
17
- ?>
18
- <script>
19
-
20
-
21
-
22
- setInterval(function() {
23
- var ajax_window_opacity = jQuery('#TB_window').css('opacity');
24
- if ( ajax_window_opacity < 1 ) {
25
-
26
- }
27
- }, 50 );
28
-
29
-
30
- var chart = null,
31
- pie_chart_options = {
32
- chart: {
33
- plotBackgroundColor: null,
34
- plotBorderWidth: null,
35
- plotShadow: true,
36
- spacingTop: 50,
37
- renderTo: 'pie_chart_data'
38
- },
39
- title: {
40
- text: ''
41
- },
42
- tooltip: {
43
- pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>'
44
- },
45
- plotOptions: {
46
- pie: {
47
- size: "75%",
48
- allowPointSelect: true,
49
- cursor: 'pointer',
50
- dataLabels: {
51
- enabled: true,
52
- format: '<b>{point.name}</b> <br /> % {point.percentage:.1f}',
53
- style: {
54
- color: (Highcharts.theme && Highcharts.theme.contrastTextColor) || 'black',
55
- width: 150
56
- }
57
- }
58
- }
59
- },
60
- series: [{
61
- type: 'pie',
62
- name: 'Click Percentage',
63
- data: [
64
- <?php
65
- foreach ( $the_pie_chart_data_array as $data ) {
66
- echo '[' . $data . '] ,';
67
- }
68
- ?>
69
- ]
70
- }],
71
- credits: {
72
- enabled: false
73
- }
74
- }
75
-
76
- function drawDefaultChart() {
77
- chart = new Highcharts.Chart(pie_chart_options);
78
- }
79
-
80
- jQuery(document).ready(function() {
81
- // Radialize the colors
82
- /*
83
- Highcharts.getOptions().colors = Highcharts.map(Highcharts.getOptions().colors, function(color) {
84
- return {
85
- radialGradient: { cx: 0.5, cy: 0.3, r: 0.7 },
86
- stops: [
87
- [0, color],
88
- [1, Highcharts.Color(color).brighten(-0.3).get('rgb')] // darken
89
- ]
90
- };
91
- });
92
- */
93
- drawDefaultChart();
94
- });
95
- </script>
96
-
97
  <div id="pie_chart_data"></div>
1
+ <?php
2
+
3
+ $pie_chart_data = json_decode(stripslashes($pie_chart_link_data_array));
4
+
5
+ $the_pie_chart_data_array = array();
6
+
7
+ foreach ( $pie_chart_data as $chart_data ) {
8
+ $chart_data_explosion = explode( '-----' , $chart_data );
9
+ $chart_data_link = $chart_data_explosion[0];
10
+ $chart_data_percent = $chart_data_explosion[1];
11
+
12
+ array_push( $the_pie_chart_data_array , " ' " . $chart_data_link . " ' , " . str_replace( '%' , '' , $chart_data_percent) );
13
+ }
14
+
15
+ echo '<h2 style="width:100%;text-align:center;">' . __( "Link Click Percentage - Pie Chart" , "yikes-inc-easy-mailchimp-extender" ) . '</h2>';
16
+
17
+ ?>
18
+ <script>
19
+
20
+
21
+
22
+ setInterval(function() {
23
+ var ajax_window_opacity = jQuery('#TB_window').css('opacity');
24
+ if ( ajax_window_opacity < 1 ) {
25
+
26
+ }
27
+ }, 50 );
28
+
29
+
30
+ var chart = null,
31
+ pie_chart_options = {
32
+ chart: {
33
+ plotBackgroundColor: null,
34
+ plotBorderWidth: null,
35
+ plotShadow: true,
36
+ spacingTop: 50,
37
+ renderTo: 'pie_chart_data'
38
+ },
39
+ title: {
40
+ text: ''
41
+ },
42
+ tooltip: {
43
+ pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>'
44
+ },
45
+ plotOptions: {
46
+ pie: {
47
+ size: "75%",
48
+ allowPointSelect: true,
49
+ cursor: 'pointer',
50
+ dataLabels: {
51
+ enabled: true,
52
+ format: '<b>{point.name}</b> <br /> % {point.percentage:.1f}',
53
+ style: {
54
+ color: (Highcharts.theme && Highcharts.theme.contrastTextColor) || 'black',
55
+ width: 150
56
+ }
57
+ }
58
+ }
59
+ },
60
+ series: [{
61
+ type: 'pie',
62
+ name: 'Click Percentage',
63
+ data: [
64
+ <?php
65
+ foreach ( $the_pie_chart_data_array as $data ) {
66
+ echo '[' . $data . '] ,';
67
+ }
68
+ ?>
69
+ ]
70
+ }],
71
+ credits: {
72
+ enabled: false
73
+ }
74
+ }
75
+
76
+ function drawDefaultChart() {
77
+ chart = new Highcharts.Chart(pie_chart_options);
78
+ }
79
+
80
+ jQuery(document).ready(function() {
81
+ // Radialize the colors
82
+ /*
83
+ Highcharts.getOptions().colors = Highcharts.map(Highcharts.getOptions().colors, function(color) {
84
+ return {
85
+ radialGradient: { cx: 0.5, cy: 0.3, r: 0.7 },
86
+ stops: [
87
+ [0, color],
88
+ [1, Highcharts.Color(color).brighten(-0.3).get('rgb')] // darken
89
+ ]
90
+ };
91
+ });
92
+ */
93
+ drawDefaultChart();
94
+ });
95
+ </script>
96
+
97
  <div id="pie_chart_data"></div>
templates/mailChimp-campaign-report.php CHANGED
@@ -1,548 +1,548 @@
1
- <?php
2
- // get our data from the MailChimp API Response
3
- $campaign = $resp;
4
- // Load Thickbox
5
- add_thickbox();
6
- ?>
7
-
8
- <style>
9
- *, *:before, *:after {
10
- box-sizing: border-box;
11
- }
12
- .midnight-blue-flat-button {
13
- position: relative;
14
- vertical-align: top;
15
- width: 215px;
16
- height: 45px;
17
- padding: 0;
18
- font-size: 14px;
19
- color: white;
20
- text-align: center;
21
- text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
22
- background: #2c3e50;
23
- border: 0;
24
- border-bottom: 2px solid #22303f;
25
- cursor: pointer;
26
- -webkit-box-shadow: inset 0 -2px #22303f;
27
- box-shadow: inset 0 -2px #22303f;
28
- width: 215px;
29
- }
30
-
31
- .midnight-blue-flat-button:active {
32
- top: 1px;
33
- outline: none;
34
- -webkit-box-shadow: none;
35
- box-shadow: none;
36
- }
37
-
38
- .asbestos-flat-button {
39
- position: relative;
40
- vertical-align: top;
41
- width: 150px;
42
- height: 40px;
43
- padding: 0;
44
- font-size: 16px;
45
- color:white;
46
- text-align: center;
47
- text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
48
- background: #7f8c8d;
49
- border: 0;
50
- border-bottom: 2px solid #6d7b7c;
51
- cursor: pointer;
52
- -webkit-box-shadow: inset 0 -2px #6d7b7c;
53
- box-shadow: inset 0 -2px #6d7b7c;
54
- }
55
- .asbestos-flat-button:active {
56
- top: 1px;
57
- outline: none;
58
- -webkit-box-shadow: none;
59
- box-shadow: none;
60
- }
61
- </style>
62
-
63
- <script type="text/javascript">
64
- jQuery(function() {
65
-
66
- // append our no print class to the adminmenuwrap
67
- jQuery('#adminmenuwrap').addClass('yks-mc-no-print');
68
- jQuery('#adminmenuback').addClass('yks-mc-no-print');
69
- jQuery('#wpfooter').addClass('yks-mc-no-print');
70
-
71
- jQuery('.progressbar').each(function(){
72
- var t = jQuery(this),
73
- dataperc = t.attr('data-perc'),
74
- barperc = Math.round(dataperc*5.56);
75
- t.find('.bar').animate({width:barperc}, dataperc*25);
76
- t.find('.label').append('<div class="perc"></div>');
77
-
78
- function perc() {
79
- var length = t.find('.bar').css('width'),
80
- perc = Math.round(parseInt(length)/5.56),
81
- labelpos = (parseInt(length)-2);
82
- }
83
- perc();
84
- setInterval(perc, 0);
85
- });
86
-
87
- });
88
-
89
- jQuery('.campaign-stats-button').off().on( 'click' , function() {
90
- // clear our divs
91
- jQuery('#click_tracking_info').html('');
92
- jQuery('#geo_data_link_map').html('');
93
-
94
- // get and store the active parent button,
95
- // which dictates if we query Growth History Stats
96
- // or Campaign Stats
97
- var active_list_button = jQuery('.list_container_for_stats').find('.active_button').text();
98
- // AJAX request to get campaign report data
99
- jQuery('.mailChimpStatisticsDiv').html('<img class="mailChimp_get_subscribers_preloader" src="<?php echo admin_url().'/images/wpspin_light.gif'; ?>" style="padding-top:4em;" alt="preloader" >');
100
- var apiKey = '<?php echo $this->optionVal['api-key']; ?>';
101
- jQuery.ajax({
102
- type: 'POST',
103
- url: ajaxurl,
104
- data: {
105
- action: 'yks_mailchimp_form',
106
- form_action: 'yks_get_campaign_data',
107
- api_key: apiKey
108
- },
109
- dataType: 'html',
110
- success: function(response) {
111
- // show the parent buttons
112
- jQuery('.statistics-sub-title').show();
113
- // re-add it to the clicked element
114
- jQuery('.statistics-sub-title.campaign-stats-button').addClass('active-parent-button');
115
- // reload the All campaigns page
116
- jQuery('.mailChimpStatisticsDiv').html('<div>'+response+'</div>');
117
- }
118
- });
119
-
120
-
121
- });
122
-
123
-
124
- jQuery( '.yks-mc-view-recipients' ).off().on( 'click' , function() {
125
-
126
- var campaign_id = jQuery( '#yks-mc-this-campaign-id' ).val();
127
- var apiKey = '<?php echo $this->optionVal['api-key']; ?>';
128
- jQuery.ajax({
129
- type: 'POST',
130
- url: ajaxurl,
131
- data: {
132
- action: 'yks_mailchimp_form',
133
- form_action: 'yks_get_campaign_emailed_to',
134
- api_key: apiKey,
135
- campaign_id: campaign_id
136
- // campaign_id: jQuery(this).attr('alt')
137
- },
138
- dataType: 'html',
139
- success: function(response) {
140
- jQuery('#TB_ajaxContent').html('<div>'+response+'</div>');
141
- }
142
- });
143
-
144
- });
145
-
146
- /* Clicks Click */
147
- jQuery( '.yks_mc_clicked_data' ).off().on( 'click' , function() {
148
-
149
- // smooth scroll down to click chart
150
- jQuery('html, body').animate({
151
- scrollTop: jQuery("#click_tracking_info").offset().top
152
- }, 800);
153
-
154
- });
155
-
156
- /* Opened Click */
157
- jQuery( '.yks_mc_opened_data' ).off().on( 'click' , function() {
158
-
159
- // ajax request, get data for users who opened this campaign
160
- // display it in a thickbox popup
161
- var campaign_id = jQuery( '#yks-mc-this-campaign-id' ).val();
162
- var apiKey = '<?php echo $this->optionVal['api-key']; ?>';
163
- jQuery.ajax({
164
- type: 'POST',
165
- url: ajaxurl,
166
- data: {
167
- action: 'yks_mailchimp_form',
168
- form_action: 'yks_get_campaign_opened_data',
169
- api_key: apiKey,
170
- campaign_id: campaign_id
171
- // campaign_id: jQuery(this).attr('alt')
172
- },
173
- dataType: 'html',
174
- success: function(response) {
175
- jQuery('#TB_ajaxContent').html(response);
176
- }
177
- });
178
-
179
-
180
- });
181
-
182
- /* Bounced Click */
183
- jQuery( '.yks_mc_bounced_data' ).off().on( 'click' , function() {
184
-
185
- // ajax request, get data for users who opened this campaign
186
- // display it in a thickbox popup
187
- var campaign_id = jQuery( '#yks-mc-this-campaign-id' ).val();
188
- var apiKey = '<?php echo $this->optionVal['api-key']; ?>';
189
- jQuery.ajax({
190
- type: 'POST',
191
- url: ajaxurl,
192
- data: {
193
- action: 'yks_mailchimp_form',
194
- form_action: 'yks_get_bounced_email_data',
195
- api_key: apiKey,
196
- campaign_id: campaign_id
197
- // campaign_id: jQuery(this).attr('alt')
198
- },
199
- dataType: 'html',
200
- success: function(response) {
201
- jQuery('#TB_ajaxContent').html(response);
202
- }
203
- });
204
-
205
-
206
- });
207
-
208
- /* Unsubscribes Click */
209
- jQuery( '.yks_mc_unsubscribe_data' ).off().on( 'click' , function() {
210
-
211
- // ajax request, get data for users who opened this campaign
212
- // display it in a thickbox popup
213
- var campaign_id = jQuery( '#yks-mc-this-campaign-id' ).val();
214
- var apiKey = '<?php echo $this->optionVal['api-key']; ?>';
215
- jQuery.ajax({
216
- type: 'POST',
217
- url: ajaxurl,
218
- data: {
219
- action: 'yks_mailchimp_form',
220
- form_action: 'yks_get_unsubscribed_email_data',
221
- api_key: apiKey,
222
- campaign_id: campaign_id
223
- // campaign_id: jQuery(this).attr('alt')
224
- },
225
- dataType: 'html',
226
- success: function(response) {
227
- jQuery('#TB_ajaxContent').html(response);
228
- }
229
- });
230
-
231
-
232
- });
233
-
234
-
235
- setInterval(function() {
236
- // re-appending our preloader to hidden thickbox
237
- if ( jQuery('#TB_window').is(':visible') ) {
238
- // do nothing
239
- } else {
240
- jQuery('#yks_mc_thickbox_data').html('<img class="mailChimp_get_subscribers_preloader" src="<?php echo admin_url().'/images/wpspin_light.gif'; ?>" alt="preloader">');
241
- }
242
-
243
- }, 150);
244
- </script>
245
-
246
- <?php
247
-
248
- $timezone = get_option('timezone_string');
249
- $web_id = $campaign_web_Id;
250
- $open_percentage = round((float)($campaign['unique_opens']/$campaign['emails_sent']) * 100 ) . '%';
251
- $click_rate_percentage = round((float)($campaign['users_who_clicked']/$campaign['emails_sent']) * 100 ) . '%';
252
- $campaign_industry = $campaign['industry']['type'];
253
- $campaign_industry_open_rate = $campaign['industry']['open_rate'];
254
- $campaign_industry_click_rate = $campaign['industry']['click_rate'];
255
-
256
- $campaign_unsubscribes = $campaign['unsubscribes'];
257
- $total_opens = $campaign['opens'];
258
- $campaign_forwards = $campaign['forwards'];
259
- $campaign_abuse_reports = $campaign['abuse_reports'];
260
-
261
- // if ( isset ( $campaign['users_who_clicked'] ) && $campaign['users_who_clicked'] != '' ) {
262
- $campaign_clicks = $campaign['users_who_clicked'];
263
- $campaign_bounces = $campaign['hard_bounces'] + $campaign['soft_bounces'];
264
- $campaign_opens = $campaign['unique_opens'];
265
- if ( $campaign_opens == 0 ) {
266
- $campaign_clicks_per_unique_open = '0 %';
267
- } else {
268
- $campaign_clicks_per_unique_open = round((float)($campaign_clicks/$campaign_opens) * 100 ) . '%';
269
- }
270
- /*
271
- } else {
272
- $campaign_clicks = $campaign['users_who_clicked'];
273
- $campaign_bounces = $campaign['hard_bounces'] + $campaign['soft_bounces'];
274
- $campaign_opens = $campaign['unique_opens'];
275
- $campaign_clicks_per_unique_open = round((float)($campaign_clicks/$campaign_opens) * 100 ) . '%';
276
- }
277
- */
278
-
279
- $campaign_total_clicks = $campaign['clicks'];
280
-
281
- if ( isset ( $campaign['last_open'] ) && $campaign['last_open'] != '' ) {
282
- $last_opened_explosion = explode( ' ' , $campaign['last_open']);
283
- $last_opened_date = $last_opened_explosion[0];
284
- $last_opened_time = $last_opened_explosion[1];
285
- } else {
286
- $last_opened_date = 'Campaign Not Yet Opened';
287
- $last_opened_time = '';
288
- }
289
-
290
- if ( isset ( $campaign['last_click'] ) && $campaign['last_click'] != '' ) {
291
- $last_clicked_explosion = explode( ' ' , $campaign['last_click']);
292
- $last_clicked_date = $last_clicked_explosion[0];
293
- $last_clicked_time = $last_clicked_explosion[1];
294
- } else {
295
- $last_clicked_date = 'Campaign Not Yet Clicked';
296
- $last_clicked_time = '';
297
- }
298
-
299
- $campaign_successful_delivieries = $campaign['emails_sent'] - $campaign_bounces;
300
-
301
- $delivery_percentages = round((float)( $campaign_successful_delivieries / $campaign['emails_sent'] ) * 100 ) . '%';
302
-
303
- $industry_open_rate = round((float)$campaign['industry']['open_rate'] * 100 ) . '%';
304
- $industry_click_rate = round((float)$campaign['industry']['click_rate'] * 100 ) . '%';
305
-
306
- $campaign_24hr_time_data = $campaign['timeseries']
307
- ?>
308
- <section class="overview_information_section" style="float:right;width:auto;">
309
- <a href="#" onclick="return false;" class="campaign-stats-button yks-mc-no-print" title="<?php _e( 'Back to Campaigns' , 'yikes-inc-easy-mailchimp-extender' ); ?>" >
310
- <input type="button" href="#" onclick="return false;" class="midnight-blue-flat-button" value="<?php _e( 'Back to Campaigns' , 'yikes-inc-easy-mailchimp-extender' ); ?>">
311
- </a>
312
- </section>
313
-
314
- <!--
315
- thickbox data for opened, bounced and unsubscribed data
316
- populated via ajax
317
- -->
318
- <div id="yks_mc_thickbox_data" style="display:none;"></div>
319
-
320
- <input type="hidden" id="yks-mc-this-campaign-id" value="<?php echo $campaign_id; ?>">
321
-
322
- <div id="yks-mc-specific-campaign-report">
323
-
324
- <h2><?php _e('Campaign Statistics Report', 'yikes-inc-easy-mailchimp-extender'); ?></h2>
325
-
326
- <h2><?php echo $campaign_title; ?></h2>
327
-
328
- <!-- open tracking disabled warning -->
329
- <div id="open_tracking_disabled_warning">
330
- <div class="dashicons dashicons-info"></div>
331
- <p><strong><?php _e('Open tracking was disabled on this campaign', 'yikes-inc-easy-mailchimp-extender'); ?></strong></p>
332
- <p><?php _e('You did not enable open tracking for this campaign, so the data in this report will be incomplete.', 'yikes-inc-easy-mailchimp-extender'); ?> <a href="http://kb.mailchimp.com/article/about-open-tracking?t=1403809717&v=170&enc=bffd7faa880038136e94f98b489a89a29b02f86fcfd1aafd1616b2ad4695fff3" target="_blank"><?php _e('about open tracking', 'yikes-inc-easy-mailchimp-extender'); ?></a>.</p>
333
- </div>
334
-
335
- <hr />
336
- <hr />
337
-
338
- <h2><?php _e('Overview', 'yikes-inc-easy-mailchimp-extender'); ?></h2>
339
- <h3 class="yks-campaign-report-recipients"><a href="#TB_inline?width=975&height=650&inlineId=yks-campaign-report-email-recipients-table" onclick="return false;" class="yks-mc-view-recipients thickbox"><?php echo $campaign['emails_sent']; ?></a> <?php _e('Recipients', 'yikes-inc-easy-mailchimp-extender'); ?></h3>
340
-
341
- <div id="yks-campaign-report-email-recipients-table" class="yks-mc-no-print" style="display:none;">
342
- <img class="mailChimp_get_subscribers_preloader" src="<?php echo admin_url().'/images/wpspin_light.gif'; ?>" style="padding-top:4em;" alt="preloader" >
343
- </div>
344
-
345
-
346
- <div class="overview-info-container">
347
-
348
- <!-- Display our buttons to let the user print/download/view email of this specific report -->
349
- <span class="overview_information">
350
- <strong><?php _e('Subject', 'yikes-inc-easy-mailchimp-extender'); ?> </strong> <?php echo $campaign_email_subject; ?><br />
351
- <strong><?php _e('Delivered', 'yikes-inc-easy-mailchimp-extender'); ?> </strong> <?php echo date( "D, M j, Y" , strtotime($campaign_send_date) ) . ' ' . date( "g:i a" , strtotime($campaign_send_time) ); ?><br />
352
- </span>
353
-
354
- <!-- Display our buttons to let the user print/download/view email of this specific report -->
355
- <span class="overview_information" style="min-height:64px;text-align:right;float:right;">
356
- <a href="<?php echo $campaign_view_email_link; ?>" class="thickbox" onclick="return false;"><input type="button" href="#" onclick="return false;" class="asbestos-flat-button yks-mc-no-print" value="<?php _e( 'View Email' , 'yikes-inc-easy-mailchimp-extender' ); ?>"></a>
357
- <a onclick="window.open('https://us3.admin.mailchimp.com/reports/excel?id=<?php echo $web_id; ?>');"><input type="button" href="#" onclick="return false;" class="asbestos-flat-button yks-mc-no-print" value="<?php _e( 'Download Report' , 'yikes-inc-easy-mailchimp-extender' ); ?>"></a>
358
- <input type="button" href="#" onclick="window.print();" class="asbestos-flat-button yks-mc-no-print" value="<?php _e( 'Print Report' , 'yikes-inc-easy-mailchimp-extender' ); ?>"></a>
359
- </span>
360
-
361
-
362
- <section class="overview_information_section">
363
-
364
- <!-- Display our buttons to let the user print/download/view email of this specific report -->
365
- <span class="overview_information overview_information_right">
366
- <span class="info_overview_avg_tag"><h3><?php _e('Open Rate', 'yikes-inc-easy-mailchimp-extender'); ?> <strong class="info_overview_percentage"><?php echo $open_percentage; ?></strong></h3></span>
367
- <!-- progress bar -->
368
- <div class="progress-bar green stripes progress-bar-open-rate yks-mc-no-print">
369
- <span style="width: <?php echo $open_percentage; ?>"></span>
370
- </div>
371
- <!-- <span class="info_overview_avg_tag">List avg <strong class="info_overview_percentage"></strong></span> -->
372
- <span class="info_overview_avg_tag"><?php _e('Industry Avg', 'yikes-inc-easy-mailchimp-extender'); ?> (<?php echo $campaign_industry; ?>) <strong class="info_overview_percentage"><?php echo $industry_open_rate; ?></strong></span>
373
- </span>
374
-
375
- <!-- Display our buttons to let the user print/download/view email of this specific report -->
376
- <span class="overview_information">
377
- <span class="info_overview_avg_tag"><h3><?php _e('Click Rate', 'yikes-inc-easy-mailchimp-extender'); ?> <strong class="info_overview_percentage"><?php echo $click_rate_percentage; ?></strong></h3></span>
378
- <!-- progress bar -->
379
- <div class="progress-bar green stripes shine progress-bar-click-rate yks-mc-no-print">
380
- <span style="width: <?php echo $click_rate_percentage; ?>"></span>
381
- </div>
382
- <div class="progressbar-click-rate"><div class="progress-click-rate" ><div class="pbaranim-click-rate"></div></div></div>
383
- <!-- <span class="info_overview_avg_tag">List avg <strong class="info_overview_percentage"></strong></span> -->
384
- <span class="info_overview_avg_tag"><?php _e('Industry Avg', 'yikes-inc-easy-mailchimp-extender'); ?> (<?php echo $campaign_industry; ?>) <strong class="info_overview_percentage"><?php echo $industry_click_rate; ?></strong></span>
385
- </span>
386
-
387
- <div id="opened_clicked_bounced_unsubscribed">
388
- <span class="centered_container">
389
- <a href="#TB_inline?width=600&height=550&inlineId=yks_mc_thickbox_data" class="thickbox yks_mc_opened_data">
390
- <span class="yks_mc_ocbu">
391
- <p class="yks_mc_ocbu_number"><?php echo $campaign_opens; ?></p>
392
- <strong><?php _e('Opened', 'yikes-inc-easy-mailchimp-extender'); ?></strong>
393
- </span>
394
- </a>
395
- <span class="yks_mc_ocbu yks_mc_clicked_data">
396
- <p class="yks_mc_ocbu_number"><?php echo $campaign_clicks; ?></p>
397
- <strong><?php _e('Clicked', 'yikes-inc-easy-mailchimp-extender'); ?></strong>
398
- </span>
399
- <a href="#TB_inline?width=600&height=550&inlineId=yks_mc_thickbox_data" class="thickbox yks_mc_bounced_data">
400
- <span class="yks_mc_ocbu yks_mc_bounced_data">
401
- <p class="yks_mc_ocbu_number"><?php echo $campaign_bounces; ?></p>
402
- <strong><?php _e('Bounced', 'yikes-inc-easy-mailchimp-extender'); ?></strong>
403
- </span>
404
- </a>
405
- <a href="#TB_inline?width=600&height=550&inlineId=yks_mc_thickbox_data" class="thickbox yks_mc_unsubscribe_data">
406
- <span class="yks_mc_ocbu yks_mc_unsubscribed_data">
407
- <p class="yks_mc_ocbu_number"><?php echo $campaign_unsubscribes; ?></p>
408
- <strong><?php _e('Unsubscribed', 'yikes-inc-easy-mailchimp-extender'); ?></strong>
409
- </span>
410
- </a>
411
- </span>
412
- </div>
413
-
414
-
415
- <span class="overview_information">
416
- <strong><?php _e('Successful deliveries', 'yikes-inc-easy-mailchimp-extender'); ?></strong> <?php echo $campaign_successful_delivieries; ?> <span class="overview_percentage" style="font-size:15px;"> (<?php echo $delivery_percentages; ?>) </span><br />
417
- <strong><?php _e('Total opens', 'yikes-inc-easy-mailchimp-extender'); ?></strong> <?php echo $total_opens; ?><br />
418
- <strong><?php _e('Last opened', 'yikes-inc-easy-mailchimp-extender'); ?></strong> <?php if ( isset ( $campaign['last_open'] ) && $campaign['last_open'] != '' ) { echo date( "m/d/y" , strtotime($last_opened_date) ) . ' at ' . date( "g:i a" , strtotime($last_opened_time) ); } else { echo 'Campaign Not Yet Opened'; } ?><br />
419
- <strong><?php _e('Forwarded', 'yikes-inc-easy-mailchimp-extender'); ?></strong> <?php echo $campaign_forwards; ?><br />
420
- </span>
421
-
422
- <span class="overview_information">
423
- <strong><?php _e('Clicks per unique opens', 'yikes-inc-easy-mailchimp-extender'); ?></strong> <?php echo $campaign_clicks_per_unique_open; ?><br />
424
- <strong><?php _e('Total clicks', 'yikes-inc-easy-mailchimp-extender'); ?></strong> <?php echo $campaign_total_clicks; ?><br />
425
- <strong><?php _e('Last clicked', 'yikes-inc-easy-mailchimp-extender'); ?></strong> <?php if ( isset ( $campaign['last_click'] ) && $campaign['last_click'] != '' ) { echo date( "m/d/y" , strtotime($last_clicked_date) ) . ' at ' . date( "g:i a" , strtotime($last_clicked_time) ); } else { echo 'No Links Clicked Yet'; } ?><br />
426
- <strong><?php _e('Abuse reports', 'yikes-inc-easy-mailchimp-extender'); ?></strong> <?php echo $campaign_abuse_reports; ?><br />
427
- </span>
428
-
429
- </section>
430
-
431
- <section class="overview_information_section">
432
-
433
- <h2><?php _e('Campaign Link Performance', 'yikes-inc-easy-mailchimp-extender'); ?></h2>
434
- <div class="overview_information" style="width:100%;">
435
- <?php
436
- // create an array of our returned data,
437
- // used in the chart
438
- $campaign_chart_time_array = array();
439
- $campaign_chart_unique_opens_array = array();
440
- $campaign_chart_unique_clicks_array = array();
441
-
442
- // print_r($campaign_24hr_time_data);
443
- foreach ( $campaign_24hr_time_data as $time_data ) {
444
- $time_explosion = explode( ' ' , $time_data['timestamp'] );
445
- array_push( $campaign_chart_time_array , date( 'g:i a' , strtotime( $time_explosion[1] ) ) );
446
- array_push( $campaign_chart_unique_opens_array , $time_data['unique_opens'] );
447
- array_push( $campaign_chart_unique_clicks_array, $time_data['recipients_click'] );
448
- }
449
-
450
- // print_r($campaign_chart_time_array);
451
- // print_r($campaign_chart_unique_opens_array);
452
- // print_r($campaign_chart_unique_clicks_array);
453
- ?>
454
-
455
- <!-- 24 hour performance chart javascript -->
456
- <script type="text/javascript">
457
- jQuery(window).on( 'scroll' , allInView);
458
-
459
- function isScrolledIntoView(elem) {
460
- var docViewTop = jQuery(window).scrollTop();
461
- var docViewBottom = docViewTop + jQuery(window).height();
462
-
463
- var elemTop = jQuery(elem).offset().top;
464
- var elemBottom = elemTop + jQuery(elem).height();
465
-
466
- return (elemBottom <= docViewBottom);
467
- }
468
-
469
- function allInView() {
470
-
471
- // function gets fired many times,
472
- // need to fire function one time
473
- // prevents function from running
474
- // when the element doesn't exist
475
- // (prevents errors from being thrown)
476
- if ( jQuery('#yks-admin-campaign-stats-table').is(':visible') ) {
477
- return false;
478
- } else if ( jQuery( '.mailChimp_get_subscribers_preloader' ).is(':visible') ) {
479
- return false;
480
- } else {
481
- if (isScrolledIntoView(jQuery("#24hr_line_chart"))) {
482
- if ( jQuery('#24hr_line_chart').is(':empty') ) {
483
- jQuery('#24hr_line_chart').stop().animate({
484
- height: '400px'
485
- }, 600, function() {
486
- jQuery('#24hr_line_chart').highcharts({
487
- chart: {
488
- type: 'line'
489
- },
490
- title: {
491
- text: "<?php _e('24 Hour Campaign Performance', 'yikes-inc-easy-mailchimp-extender'); ?>"
492
- },
493
- subtitle: {
494
- text: "<?php _e('begins from the time your campaign is sent', 'yikes-inc-easy-mailchimp-extender'); ?>"
495
- },
496
- xAxis: {
497
- // time array
498
- categories: [<?php echo '"' . implode( ' ", "' , $campaign_chart_time_array ) .'"'; ?>]
499
- },
500
- yAxis: {
501
- title: {
502
- text: "<?php _e('Number of Opens/Clicks', 'yikes-inc-easy-mailchimp-extender'); ?>"
503
- },
504
- min: 0,
505
- },
506
- plotOptions: {
507
- line: {
508
- dataLabels: {
509
- enabled: true
510
- },
511
- enableMouseTracking: true
512
- }
513
- },
514
- credits: {
515
- enabled: false
516
- },
517
- series: [{
518
- name: "<?php _e('Unique Opens', 'yikes-inc-easy-mailchimp-extender'); ?>",
519
- data: [<?php echo implode( ', ' , $campaign_chart_unique_opens_array ); ?>]
520
- }, {
521
- name: "<?php _e('Unique Clicks', 'yikes-inc-easy-mailchimp-extender'); ?>",
522
- data: [<?php echo implode( ', ' , $campaign_chart_unique_clicks_array ); ?>]
523
- }]
524
- });
525
- });
526
- }
527
- }
528
- }
529
- }
530
- </script>
531
-
532
- <div id="24hr_line_chart" style="min-width: 100%; margin: 0 auto"></div>
533
-
534
- </div>
535
-
536
-
537
-
538
- </section>
539
-
540
-
541
-
542
- </div>
543
-
544
-
545
-
546
- <strong></strong>
547
-
548
- </div>
1
+ <?php
2
+ // get our data from the MailChimp API Response
3
+ $campaign = $resp;
4
+ // Load Thickbox
5
+ add_thickbox();
6
+ ?>
7
+
8
+ <style>
9
+ .midnight-blue-flat-button {
10
+ position: relative;
11
+ vertical-align: top;
12
+ width: 215px;
13
+ height: 45px;
14
+ padding: 0;
15
+ font-size: 14px;
16
+ color: white;
17
+ text-align: center;
18
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
19
+ background: #2c3e50;
20
+ border: 0;
21
+ border-bottom: 2px solid #22303f;
22
+ cursor: pointer;
23
+ -webkit-box-shadow: inset 0 -2px #22303f;
24
+ box-shadow: inset 0 -2px #22303f;
25
+ width: 215px;
26
+ }
27
+
28
+ .midnight-blue-flat-button:active {
29
+ top: 1px;
30
+ outline: none;
31
+ -webkit-box-shadow: none;
32
+ box-shadow: none;
33
+ }
34
+
35
+ .asbestos-flat-button {
36
+ position: relative;
37
+ vertical-align: top;
38
+ width: 150px;
39
+ height: 40px;
40
+ padding: 0;
41
+ font-size: 16px;
42
+ color:white;
43
+ text-align: center;
44
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
45
+ background: #7f8c8d;
46
+ border: 0;
47
+ border-bottom: 2px solid #6d7b7c;
48
+ cursor: pointer;
49
+ -webkit-box-shadow: inset 0 -2px #6d7b7c;
50
+ box-shadow: inset 0 -2px #6d7b7c;
51
+ }
52
+ .asbestos-flat-button:active {
53
+ top: 1px;
54
+ outline: none;
55
+ -webkit-box-shadow: none;
56
+ box-shadow: none;
57
+ }
58
+ *, *:before, *:after {
59
+ box-sizing: border-box;
60
+ }
61
+ </style>
62
+
63
+ <script type="text/javascript">
64
+ jQuery(function() {
65
+
66
+ // append our no print class to the adminmenuwrap
67
+ jQuery('#adminmenuwrap').addClass('yks-mc-no-print');
68
+ jQuery('#adminmenuback').addClass('yks-mc-no-print');
69
+ jQuery('#wpfooter').addClass('yks-mc-no-print');
70
+
71
+ jQuery('.progressbar').each(function(){
72
+ var t = jQuery(this),
73
+ dataperc = t.attr('data-perc'),
74
+ barperc = Math.round(dataperc*5.56);
75
+ t.find('.bar').animate({width:barperc}, dataperc*25);
76
+ t.find('.label').append('<div class="perc"></div>');
77
+
78
+ function perc() {
79
+ var length = t.find('.bar').css('width'),
80
+ perc = Math.round(parseInt(length)/5.56),
81
+ labelpos = (parseInt(length)-2);
82
+ }
83
+ perc();
84
+ setInterval(perc, 0);
85
+ });
86
+
87
+ });
88
+
89
+ jQuery('.campaign-stats-button').off().on( 'click' , function() {
90
+ // clear our divs
91
+ jQuery('#click_tracking_info').html('');
92
+ jQuery('#geo_data_link_map').html('');
93
+
94
+ // get and store the active parent button,
95
+ // which dictates if we query Growth History Stats
96
+ // or Campaign Stats
97
+ var active_list_button = jQuery('.list_container_for_stats').find('.active_button').text();
98
+ // AJAX request to get campaign report data
99
+ jQuery('.mailChimpStatisticsDiv').html('<img class="mailChimp_get_subscribers_preloader" src="<?php echo admin_url().'/images/wpspin_light.gif'; ?>" style="padding-top:4em;" alt="preloader" >');
100
+ var apiKey = '<?php echo $this->optionVal['api-key']; ?>';
101
+ jQuery.ajax({
102
+ type: 'POST',
103
+ url: ajaxurl,
104
+ data: {
105
+ action: 'yks_mailchimp_form',
106
+ form_action: 'yks_get_campaign_data',
107
+ api_key: apiKey
108
+ },
109
+ dataType: 'html',
110
+ success: function(response) {
111
+ // show the parent buttons
112
+ jQuery('.statistics-sub-title').show();
113
+ // re-add it to the clicked element
114
+ jQuery('.statistics-sub-title.campaign-stats-button').addClass('active-parent-button');
115
+ // reload the All campaigns page
116
+ jQuery('.mailChimpStatisticsDiv').html('<div>'+response+'</div>');
117
+ }
118
+ });
119
+
120
+
121
+ });
122
+
123
+
124
+ jQuery( '.yks-mc-view-recipients' ).off().on( 'click' , function() {
125
+
126
+ var campaign_id = jQuery( '#yks-mc-this-campaign-id' ).val();
127
+ var apiKey = '<?php echo $this->optionVal['api-key']; ?>';
128
+ jQuery.ajax({
129
+ type: 'POST',
130
+ url: ajaxurl,
131
+ data: {
132
+ action: 'yks_mailchimp_form',
133
+ form_action: 'yks_get_campaign_emailed_to',
134
+ api_key: apiKey,
135
+ campaign_id: campaign_id
136
+ // campaign_id: jQuery(this).attr('alt')
137
+ },
138
+ dataType: 'html',
139
+ success: function(response) {
140
+ jQuery('#TB_ajaxContent').html('<div>'+response+'</div>');
141
+ }
142
+ });
143
+
144
+ });
145
+
146
+ /* Clicks Click */
147
+ jQuery( '.yks_mc_clicked_data' ).off().on( 'click' , function() {
148
+
149
+ // smooth scroll down to click chart
150
+ jQuery('html, body').animate({
151
+ scrollTop: jQuery("#yks-admin-link-data-table").offset().top - 220
152
+ }, 800);
153
+
154
+ });
155
+
156
+ /* Opened Click */
157
+ jQuery( '.yks_mc_opened_data' ).off().on( 'click' , function() {
158
+
159
+ // ajax request, get data for users who opened this campaign
160
+ // display it in a thickbox popup
161
+ var campaign_id = jQuery( '#yks-mc-this-campaign-id' ).val();
162
+ var apiKey = '<?php echo $this->optionVal['api-key']; ?>';
163
+ jQuery.ajax({
164
+ type: 'POST',
165
+ url: ajaxurl,
166
+ data: {
167
+ action: 'yks_mailchimp_form',
168
+ form_action: 'yks_get_campaign_opened_data',
169
+ api_key: apiKey,
170
+ campaign_id: campaign_id
171
+ // campaign_id: jQuery(this).attr('alt')
172
+ },
173
+ dataType: 'html',
174
+ success: function(response) {
175
+ jQuery('#TB_ajaxContent').html(response);
176
+ }
177
+ });
178
+
179
+
180
+ });
181
+
182
+ /* Bounced Click */
183
+ jQuery( '.yks_mc_bounced_data' ).off().on( 'click' , function() {
184
+
185
+ // ajax request, get data for users who opened this campaign
186
+ // display it in a thickbox popup
187
+ var campaign_id = jQuery( '#yks-mc-this-campaign-id' ).val();
188
+ var apiKey = '<?php echo $this->optionVal['api-key']; ?>';
189
+ jQuery.ajax({
190
+ type: 'POST',
191
+ url: ajaxurl,
192
+ data: {
193
+ action: 'yks_mailchimp_form',
194
+ form_action: 'yks_get_bounced_email_data',
195
+ api_key: apiKey,
196
+ campaign_id: campaign_id
197
+ // campaign_id: jQuery(this).attr('alt')
198
+ },
199
+ dataType: 'html',
200
+ success: function(response) {
201
+ jQuery('#TB_ajaxContent').html(response);
202
+ }
203
+ });
204
+
205
+
206
+ });
207
+
208
+ /* Unsubscribes Click */
209
+ jQuery( '.yks_mc_unsubscribe_data' ).off().on( 'click' , function() {
210
+
211
+ // ajax request, get data for users who opened this campaign
212
+ // display it in a thickbox popup
213
+ var campaign_id = jQuery( '#yks-mc-this-campaign-id' ).val();
214
+ var apiKey = '<?php echo $this->optionVal['api-key']; ?>';
215
+ jQuery.ajax({
216
+ type: 'POST',
217
+ url: ajaxurl,
218
+ data: {
219
+ action: 'yks_mailchimp_form',
220
+ form_action: 'yks_get_unsubscribed_email_data',
221
+ api_key: apiKey,
222
+ campaign_id: campaign_id
223
+ // campaign_id: jQuery(this).attr('alt')
224
+ },
225
+ dataType: 'html',
226
+ success: function(response) {
227
+ jQuery('#TB_ajaxContent').html(response);
228
+ }
229
+ });
230
+
231
+
232
+ });
233
+
234
+
235
+ setInterval(function() {
236
+ // re-appending our preloader to hidden thickbox
237
+ if ( jQuery('#TB_window').is(':visible') ) {
238
+ // do nothing
239
+ } else {
240
+ jQuery('#yks_mc_thickbox_data').html('<img class="mailChimp_get_subscribers_preloader" src="<?php echo admin_url().'/images/wpspin_light.gif'; ?>" alt="preloader">');
241
+ }
242
+
243
+ }, 150);
244
+ </script>
245
+
246
+ <?php
247
+
248
+ $timezone = get_option('timezone_string');
249
+ $web_id = $campaign_web_Id;
250
+ $open_percentage = round((float)($campaign['unique_opens']/$campaign['emails_sent']) * 100 ) . '%';
251
+ $click_rate_percentage = round((float)($campaign['users_who_clicked']/$campaign['emails_sent']) * 100 ) . '%';
252
+ $campaign_industry = $campaign['industry']['type'];
253
+ $campaign_industry_open_rate = $campaign['industry']['open_rate'];
254
+ $campaign_industry_click_rate = $campaign['industry']['click_rate'];
255
+
256
+ $campaign_unsubscribes = $campaign['unsubscribes'];
257
+ $total_opens = $campaign['opens'];
258
+ $campaign_forwards = $campaign['forwards'];
259
+ $campaign_abuse_reports = $campaign['abuse_reports'];
260
+
261
+ // if ( isset ( $campaign['users_who_clicked'] ) && $campaign['users_who_clicked'] != '' ) {
262
+ $campaign_clicks = $campaign['users_who_clicked'];
263
+ $campaign_bounces = $campaign['hard_bounces'] + $campaign['soft_bounces'];
264
+ $campaign_opens = $campaign['unique_opens'];
265
+ if ( $campaign_opens == 0 ) {
266
+ $campaign_clicks_per_unique_open = '0 %';
267
+ } else {
268
+ $campaign_clicks_per_unique_open = round((float)($campaign_clicks/$campaign_opens) * 100 ) . '%';
269
+ }
270
+ /*
271
+ } else {
272
+ $campaign_clicks = $campaign['users_who_clicked'];
273
+ $campaign_bounces = $campaign['hard_bounces'] + $campaign['soft_bounces'];
274
+ $campaign_opens = $campaign['unique_opens'];
275
+ $campaign_clicks_per_unique_open = round((float)($campaign_clicks/$campaign_opens) * 100 ) . '%';
276
+ }
277
+ */
278
+
279
+ $campaign_total_clicks = $campaign['clicks'];
280
+
281
+ if ( isset ( $campaign['last_open'] ) && $campaign['last_open'] != '' ) {
282
+ $last_opened_explosion = explode( ' ' , $campaign['last_open']);
283
+ $last_opened_date = $last_opened_explosion[0];
284
+ $last_opened_time = $last_opened_explosion[1];
285
+ } else {
286
+ $last_opened_date = 'Campaign Not Yet Opened';
287
+ $last_opened_time = '';
288
+ }
289
+
290
+ if ( isset ( $campaign['last_click'] ) && $campaign['last_click'] != '' ) {
291
+ $last_clicked_explosion = explode( ' ' , $campaign['last_click']);
292
+ $last_clicked_date = $last_clicked_explosion[0];
293
+ $last_clicked_time = $last_clicked_explosion[1];
294
+ } else {
295
+ $last_clicked_date = 'Campaign Not Yet Clicked';
296
+ $last_clicked_time = '';
297
+ }
298
+
299
+ $campaign_successful_delivieries = $campaign['emails_sent'] - $campaign_bounces;
300
+
301
+ $delivery_percentages = round((float)( $campaign_successful_delivieries / $campaign['emails_sent'] ) * 100 ) . '%';
302
+
303
+ $industry_open_rate = round((float)$campaign['industry']['open_rate'] * 100 ) . '%';
304
+ $industry_click_rate = round((float)$campaign['industry']['click_rate'] * 100 ) . '%';
305
+
306
+ $campaign_24hr_time_data = $campaign['timeseries']
307
+ ?>
308
+ <section class="overview_information_section" style="float:right;width:auto;">
309
+ <a href="#" onclick="return false;" class="campaign-stats-button yks-mc-no-print" title="<?php _e( 'Back to Campaigns' , 'yikes-inc-easy-mailchimp-extender' ); ?>" >
310
+ <input type="button" href="#" onclick="return false;" class="midnight-blue-flat-button" value="<?php _e( 'Back to Campaigns' , 'yikes-inc-easy-mailchimp-extender' ); ?>">
311
+ </a>
312
+ </section>
313
+
314
+ <!--
315
+ thickbox data for opened, bounced and unsubscribed data
316
+ populated via ajax
317
+ -->
318
+ <div id="yks_mc_thickbox_data" style="display:none;"></div>
319
+
320
+ <input type="hidden" id="yks-mc-this-campaign-id" value="<?php echo $campaign_id; ?>">
321
+
322
+ <div id="yks-mc-specific-campaign-report">
323
+
324
+ <h2><?php _e('Campaign Statistics Report', 'yikes-inc-easy-mailchimp-extender'); ?></h2>
325
+
326
+ <h2><?php echo $campaign_title; ?></h2>
327
+
328
+ <!-- open tracking disabled warning -->
329
+ <div id="open_tracking_disabled_warning">
330
+ <div class="dashicons dashicons-info"></div>
331
+ <p><strong><?php _e('Open tracking was disabled on this campaign', 'yikes-inc-easy-mailchimp-extender'); ?></strong></p>
332
+ <p><?php _e('You did not enable open tracking for this campaign, so the data in this report will be incomplete.', 'yikes-inc-easy-mailchimp-extender'); ?> <a href="http://kb.mailchimp.com/article/about-open-tracking?t=1403809717&v=170&enc=bffd7faa880038136e94f98b489a89a29b02f86fcfd1aafd1616b2ad4695fff3" target="_blank"><?php _e('about open tracking', 'yikes-inc-easy-mailchimp-extender'); ?></a>.</p>
333
+ </div>
334
+
335
+ <hr />
336
+ <hr />
337
+
338
+ <h2><?php _e('Overview', 'yikes-inc-easy-mailchimp-extender'); ?></h2>
339
+ <h3 class="yks-campaign-report-recipients"><a href="#TB_inline?width=975&height=650&inlineId=yks-campaign-report-email-recipients-table" onclick="return false;" class="yks-mc-view-recipients thickbox"><?php echo $campaign['emails_sent']; ?></a> <?php _e('Recipients', 'yikes-inc-easy-mailchimp-extender'); ?></h3>
340
+
341
+ <div id="yks-campaign-report-email-recipients-table" class="yks-mc-no-print" style="display:none;">
342
+ <img class="mailChimp_get_subscribers_preloader" src="<?php echo admin_url().'/images/wpspin_light.gif'; ?>" style="padding-top:4em;" alt="preloader" >
343
+ </div>
344
+
345
+
346
+ <div class="overview-info-container">
347
+
348
+ <!-- Display our buttons to let the user print/download/view email of this specific report -->
349
+ <span class="overview_information">
350
+ <strong><?php _e('Subject', 'yikes-inc-easy-mailchimp-extender'); ?> </strong> <?php echo $campaign_email_subject; ?><br />
351
+ <strong><?php _e('Delivered', 'yikes-inc-easy-mailchimp-extender'); ?> </strong> <?php echo date( "D, M j, Y" , strtotime($campaign_send_date) ) . ' ' . date( "g:i a" , strtotime($campaign_send_time) ); ?><br />
352
+ </span>
353
+
354
+ <!-- Display our buttons to let the user print/download/view email of this specific report -->
355
+ <span class="overview_information" style="min-height:64px;text-align:right;float:right;">
356
+ <a href="<?php echo $campaign_view_email_link; ?>" class="thickbox" onclick="return false;"><input type="button" href="#" onclick="return false;" class="asbestos-flat-button yks-mc-no-print" value="<?php _e( 'View Email' , 'yikes-inc-easy-mailchimp-extender' ); ?>"></a>
357
+ <a onclick="window.open('https://us3.admin.mailchimp.com/reports/excel?id=<?php echo $web_id; ?>');"><input type="button" href="#" onclick="return false;" class="asbestos-flat-button yks-mc-no-print" value="<?php _e( 'Download Report' , 'yikes-inc-easy-mailchimp-extender' ); ?>"></a>
358
+ <input type="button" href="#" onclick="window.print();" class="asbestos-flat-button yks-mc-no-print" value="<?php _e( 'Print Report' , 'yikes-inc-easy-mailchimp-extender' ); ?>"></a>
359
+ </span>
360
+
361
+
362
+ <section class="overview_information_section">
363
+
364
+ <!-- Display our buttons to let the user print/download/view email of this specific report -->
365
+ <span class="overview_information overview_information_right">
366
+ <span class="info_overview_avg_tag"><h3><?php _e('Open Rate', 'yikes-inc-easy-mailchimp-extender'); ?> <strong class="info_overview_percentage"><?php echo $open_percentage; ?></strong></h3></span>
367
+ <!-- progress bar -->
368
+ <div class="progress-bar green stripes progress-bar-open-rate yks-mc-no-print">
369
+ <span style="width: <?php echo $open_percentage; ?>"></span>
370
+ </div>
371
+ <!-- <span class="info_overview_avg_tag">List avg <strong class="info_overview_percentage"></strong></span> -->
372
+ <span class="info_overview_avg_tag"><?php _e('Industry Avg', 'yikes-inc-easy-mailchimp-extender'); ?> (<?php echo $campaign_industry; ?>) <strong class="info_overview_percentage"><?php echo $industry_open_rate; ?></strong></span>
373
+ </span>
374
+
375
+ <!-- Display our buttons to let the user print/download/view email of this specific report -->
376
+ <span class="overview_information">
377
+ <span class="info_overview_avg_tag"><h3><?php _e('Click Rate', 'yikes-inc-easy-mailchimp-extender'); ?> <strong class="info_overview_percentage"><?php echo $click_rate_percentage; ?></strong></h3></span>
378
+ <!-- progress bar -->
379
+ <div class="progress-bar green stripes shine progress-bar-click-rate yks-mc-no-print">
380
+ <span style="width: <?php echo $click_rate_percentage; ?>"></span>
381
+ </div>
382
+ <div class="progressbar-click-rate"><div class="progress-click-rate" ><div class="pbaranim-click-rate"></div></div></div>
383
+ <!-- <span class="info_overview_avg_tag">List avg <strong class="info_overview_percentage"></strong></span> -->
384
+ <span class="info_overview_avg_tag"><?php _e('Industry Avg', 'yikes-inc-easy-mailchimp-extender'); ?> (<?php echo $campaign_industry; ?>) <strong class="info_overview_percentage"><?php echo $industry_click_rate; ?></strong></span>
385
+ </span>
386
+
387
+ <div id="opened_clicked_bounced_unsubscribed">
388
+ <span class="centered_container">
389
+ <a href="#TB_inline?width=600&height=550&inlineId=yks_mc_thickbox_data" class="thickbox yks_mc_opened_data">
390
+ <span class="yks_mc_ocbu">
391
+ <p class="yks_mc_ocbu_number"><?php echo $campaign_opens; ?></p>
392
+ <strong><?php _e('Opened', 'yikes-inc-easy-mailchimp-extender'); ?></strong>
393
+ </span>
394
+ </a>
395
+ <span class="yks_mc_ocbu yks_mc_clicked_data">
396
+ <p class="yks_mc_ocbu_number"><?php echo $campaign_clicks; ?></p>
397
+ <strong><?php _e('Clicked', 'yikes-inc-easy-mailchimp-extender'); ?></strong>
398
+ </span>
399
+ <a href="#TB_inline?width=600&height=550&inlineId=yks_mc_thickbox_data" class="thickbox yks_mc_bounced_data">
400
+ <span class="yks_mc_ocbu yks_mc_bounced_data">
401
+ <p class="yks_mc_ocbu_number"><?php echo $campaign_bounces; ?></p>
402
+ <strong><?php _e('Bounced', 'yikes-inc-easy-mailchimp-extender'); ?></strong>
403
+ </span>
404
+ </a>
405
+ <a href="#TB_inline?width=600&height=550&inlineId=yks_mc_thickbox_data" class="thickbox yks_mc_unsubscribe_data">
406
+ <span class="yks_mc_ocbu yks_mc_unsubscribed_data">
407
+ <p class="yks_mc_ocbu_number"><?php echo $campaign_unsubscribes; ?></p>
408
+ <strong><?php _e('Unsubscribed', 'yikes-inc-easy-mailchimp-extender'); ?></strong>
409
+ </span>
410
+ </a>
411
+ </span>
412
+ </div>
413
+
414
+
415
+ <span class="overview_information">
416
+ <strong><?php _e('Successful deliveries', 'yikes-inc-easy-mailchimp-extender'); ?></strong> <?php echo $campaign_successful_delivieries; ?> <span class="overview_percentage" style="font-size:15px;"> (<?php echo $delivery_percentages; ?>) </span><br />
417
+ <strong><?php _e('Total opens', 'yikes-inc-easy-mailchimp-extender'); ?></strong> <?php echo $total_opens; ?><br />
418
+ <strong><?php _e('Last opened', 'yikes-inc-easy-mailchimp-extender'); ?></strong> <?php if ( isset ( $campaign['last_open'] ) && $campaign['last_open'] != '' ) { echo date( "m/d/y" , strtotime($last_opened_date) ) . ' at ' . date( "g:i a" , strtotime($last_opened_time) ); } else { echo 'Campaign Not Yet Opened'; } ?><br />
419
+ <strong><?php _e('Forwarded', 'yikes-inc-easy-mailchimp-extender'); ?></strong> <?php echo $campaign_forwards; ?><br />
420
+ </span>
421
+
422
+ <span class="overview_information">
423
+ <strong><?php _e('Clicks per unique opens', 'yikes-inc-easy-mailchimp-extender'); ?></strong> <?php echo $campaign_clicks_per_unique_open; ?><br />
424
+ <strong><?php _e('Total clicks', 'yikes-inc-easy-mailchimp-extender'); ?></strong> <?php echo $campaign_total_clicks; ?><br />
425
+ <strong><?php _e('Last clicked', 'yikes-inc-easy-mailchimp-extender'); ?></strong> <?php if ( isset ( $campaign['last_click'] ) && $campaign['last_click'] != '' ) { echo date( "m/d/y" , strtotime($last_clicked_date) ) . ' at ' . date( "g:i a" , strtotime($last_clicked_time) ); } else { echo 'No Links Clicked Yet'; } ?><br />
426
+ <strong><?php _e('Abuse reports', 'yikes-inc-easy-mailchimp-extender'); ?></strong> <?php echo $campaign_abuse_reports; ?><br />
427
+ </span>
428
+
429
+ </section>
430
+
431
+ <section class="overview_information_section">
432
+
433
+ <h2><?php _e('Campaign Link Performance', 'yikes-inc-easy-mailchimp-extender'); ?></h2>
434
+ <div class="overview_information" style="width:100%;">
435
+ <?php
436
+ // create an array of our returned data,
437
+ // used in the chart
438
+ $campaign_chart_time_array = array();
439
+ $campaign_chart_unique_opens_array = array();
440
+ $campaign_chart_unique_clicks_array = array();
441
+
442
+ // print_r($campaign_24hr_time_data);
443
+ foreach ( $campaign_24hr_time_data as $time_data ) {
444
+ $time_explosion = explode( ' ' , $time_data['timestamp'] );
445
+ array_push( $campaign_chart_time_array , date( 'g:i a' , strtotime( $time_explosion[1] ) ) );
446
+ array_push( $campaign_chart_unique_opens_array , $time_data['unique_opens'] );
447
+ array_push( $campaign_chart_unique_clicks_array, $time_data['recipients_click'] );
448
+ }
449
+
450
+ // print_r($campaign_chart_time_array);
451
+ // print_r($campaign_chart_unique_opens_array);
452
+ // print_r($campaign_chart_unique_clicks_array);
453
+ ?>
454
+
455
+ <!-- 24 hour performance chart javascript -->
456
+ <script type="text/javascript">
457
+ jQuery(window).on( 'scroll' , allInView);
458
+
459
+ function isScrolledIntoView(elem) {
460
+ var docViewTop = jQuery(window).scrollTop();
461
+ var docViewBottom = docViewTop + jQuery(window).height();
462
+
463
+ var elemTop = jQuery(elem).offset().top;
464
+ var elemBottom = elemTop + jQuery(elem).height();
465
+
466
+ return (elemBottom <= docViewBottom);
467
+ }
468
+
469
+ function allInView() {
470
+
471
+ // function gets fired many times,
472
+ // need to fire function one time
473
+ // prevents function from running
474
+ // when the element doesn't exist
475
+ // (prevents errors from being thrown)
476
+ if ( jQuery('#yks-admin-campaign-stats-table').is(':visible') ) {
477
+ return false;
478
+ } else if ( jQuery( '.mailChimp_get_subscribers_preloader' ).is(':visible') ) {
479
+ return false;
480
+ } else {
481
+ if (isScrolledIntoView(jQuery("#24hr_line_chart"))) {
482
+ if ( jQuery('#24hr_line_chart').is(':empty') ) {
483
+ jQuery('#24hr_line_chart').stop().animate({
484
+ height: '400px'
485
+ }, 600, function() {
486
+ jQuery('#24hr_line_chart').highcharts({
487
+ chart: {
488
+ type: 'line'
489
+ },
490
+ title: {
491
+ text: "<?php _e('24 Hour Campaign Performance', 'yikes-inc-easy-mailchimp-extender'); ?>"
492
+ },
493
+ subtitle: {
494
+ text: "<?php _e('begins from the time your campaign is sent', 'yikes-inc-easy-mailchimp-extender'); ?>"
495
+ },
496
+ xAxis: {
497
+ // time array
498
+ categories: [<?php echo '"' . implode( ' ", "' , $campaign_chart_time_array ) .'"'; ?>]
499
+ },
500
+ yAxis: {
501
+ title: {
502
+ text: "<?php _e('Number of Opens/Clicks', 'yikes-inc-easy-mailchimp-extender'); ?>"
503
+ },
504
+ min: 0,
505
+ },
506
+ plotOptions: {
507
+ line: {
508
+ dataLabels: {
509
+ enabled: true
510
+ },
511
+ enableMouseTracking: true
512
+ }
513
+ },
514
+ credits: {
515
+ enabled: false
516
+ },
517
+ series: [{
518
+ name: "<?php _e('Unique Opens', 'yikes-inc-easy-mailchimp-extender'); ?>",
519
+ data: [<?php echo implode( ', ' , $campaign_chart_unique_opens_array ); ?>]
520
+ }, {
521
+ name: "<?php _e('Unique Clicks', 'yikes-inc-easy-mailchimp-extender'); ?>",
522
+ data: [<?php echo implode( ', ' , $campaign_chart_unique_clicks_array ); ?>]
523
+ }]
524
+ });
525
+ });
526
+ }
527
+ }
528
+ }
529
+ }
530
+ </script>
531
+
532
+ <div id="24hr_line_chart" style="min-width: 100%; margin: 0 auto"></div>
533
+
534
+ </div>
535
+
536
+
537
+
538
+ </section>
539
+
540
+
541
+
542
+ </div>
543
+
544
+
545
+
546
+ <strong></strong>
547
+
548
+ </div>
templates/mailChimp-campaign-stats-template.php CHANGED
@@ -1,380 +1,380 @@
1
- <!--
2
- *
3
- Translation for Clicks , Click , Opens, and Opens need to be re-done
4
- *
5
- -->
6
- <style>
7
- /* #Green Flat Button
8
- ==================================================*/
9
- .green-flat-button {
10
- position: relative;
11
- vertical-align: top;
12
- width: 70%;
13
- height: 45px;
14
- padding: 0;
15
- font-size: 16px;
16
- color: white;
17
- text-align: center;
18
- text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
19
- background: #27ae60;
20
- border: 0;
21
- border-bottom: 2px solid #219d55;
22
- cursor: pointer;
23
- -webkit-box-shadow: inset 0 -2px #219d55;
24
- box-shadow: inset 0 -2px #219d55;
25
- min-width: 125px;
26
- max-width: 125px;
27
- }
28
- .green-flat-button:active {
29
- top: 1px;
30
- outline: none;
31
- -webkit-box-shadow: none;
32
- box-shadow: none;
33
- }
34
- /* #Orange Flat Button
35
- ==================================================*/
36
- .orange-flat-button {
37
- position: relative;
38
- vertical-align: top;
39
- width: 70%;
40
- height: 45px;
41
- padding: 0;
42
- font-size: 16px;
43
- color: white;
44
- text-align: center;
45
- text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
46
- background: #f39c12;
47
- border: 0;
48
- border-bottom: 2px solid #e8930c;
49
- cursor: pointer;
50
- -webkit-box-shadow: inset 0 -2px #e8930c;
51
- box-shadow: inset 0 -2px #e8930c;
52
- min-width: 125px;
53
- max-width: 125px;
54
- }
55
- .orange-flat-button:active {
56
- top: 1px;
57
- outline: none;
58
- -webkit-box-shadow: none;
59
- box-shadow: none;
60
- }
61
- </style>
62
-
63
- <script type="text/javascript">
64
- // switch out opens, views etc on hover
65
- jQuery(document).ready(function() {
66
-
67
- jQuery('.yks_campaign_report_click_data').mouseenter(function() {
68
- jQuery(this).find('.original_view').hide();
69
- jQuery(this).find('.hover_view').show();
70
- });
71
- jQuery('.yks_campaign_report_click_data').mouseleave(function() {
72
- jQuery(this).find('.original_view').show();
73
- jQuery(this).find('.hover_view').hide();
74
- });
75
-
76
- // display the rss feed children
77
- jQuery('.rss_parent_button').click(function() {
78
-
79
- var campaign_id = jQuery(this).attr('alt');
80
- jQuery('.'+campaign_id+'_child_report_row').stop().fadeToggle();
81
- jQuery('.'+campaign_id+'_child_report_row').next().stop().fadeToggle();
82
-
83
- return false;
84
- });
85
-
86
-
87
- });
88
- </script>
89
- <?php
90
- // print campaign data for testing purposes
91
- // print_r($resp);
92
- echo '<h2>'.__('Previous Campaigns' , 'yikes-inc-easy-mailchimp-extender' ). '</h2>';
93
- $campaign_data = $resp['data'];
94
- $campaign_children_array = array();
95
- $timezone_offset = get_option('gmt_offset');
96
- echo '<hr />';
97
-
98
- // print_r($campaign_data);
99
-
100
- // view link thickbox url
101
- // echo $campaign['archive_url']; class="thickbox
102
- ?>
103
- <table id="yks-admin-campaign-stats-table">
104
- <tbody>
105
- <?php
106
- // loop over campaign data, and display it much in the same way MailChimp
107
- if ( !empty( $campaign_data ) ) {
108
-
109
- $child_campaign_array = array();
110
-
111
- foreach ( $campaign_data as $campaign ) {
112
- // Create our variables for the loop
113
- // create our sent time variables
114
- $campaign_type = $campaign['type'];
115
-
116
- $campaign_type_image = '<img src="' . plugins_url().'/yikes-inc-easy-mailchimp-extender/images/stats-icons/'.$campaign_type.'_icon.png' . '" alt="'.$campaign_type.'" class="'.$campaign_type.' image" />';
117
-
118
- $campaign_id = $campaign['id'];
119
- $preview_campaign_link = $campaign['archive_url'];
120
- $total_emails_sent = $campaign['emails_sent'];
121
- $campaign_email_subject = $campaign['subject'];
122
- if ( isset($campaign['send_time'] ) && $campaign['send_time'] != '' ) {
123
- $send_time_explosion = explode( " " , $campaign['send_time'] );
124
- $send_time_explode = explode( ":" , $send_time_explosion[1] );
125
- $campaign_send_time = ( $send_time_explode[0] + $timezone_offset ).':'.$send_time_explode[1];
126
- $campaign_send_date = $send_time_explosion[0];
127
- $campaign_unique_opens = $campaign['summary']['unique_opens'];
128
- $campaign_clicks = $campaign['summary']['users_who_clicked'];
129
- $campaign_web_id = $campaign['web_id'];
130
- $campaign_open_percentage = round((float)($campaign_unique_opens/$total_emails_sent) * 100 ) . '%';
131
- $user_click_percentage = round((float)($campaign_clicks/$total_emails_sent) * 100 ) . '%';
132
- } else {
133
- $campaign_send_time = '';
134
- $campaign_send_date = '<strong>Not Sent</strong>';
135
- $campaign_unique_opens = '0';
136
- $campaign_clicks = '0';
137
- $campaign_web_id = '-';
138
- $campaign_open_percentage ='0 %';
139
- $user_click_percentage = '0 %';
140
- }
141
-
142
- if ( $campaign['is_child'] != 1 ) {
143
- ?>
144
- <tr class="single_report_row <?php if ( $campaign_type == 'rss' ) { ?>rss_single_report_row <?php } ?>">
145
- <td <?php if ( !isset ( $campaign['send_time'] ) && !isset( $campaign['type_opts']['last_sent'] ) ) { ?> style="opacity:.25;" <?php } ?>>
146
- <?php echo $campaign_type_image; ?>
147
- </td>
148
- <!-- column 1 -->
149
- <td>
150
- <?php if ( isset ( $campaign['send_time'] ) ) { ?>
151
- <a class="yks_campaign_report_link yks-mc-view-report-button" href="#" onclick="return false;" alt="<?php echo $campaign_id; ?>" title="<?php echo $campaign['title']; ?>"><?php echo $campaign['title']; ?></a>
152
- <?php } else {
153
- echo '<span class="yks_campaign_report_disabled_link">'.$campaign['title'].'</span>';
154
- } ?>
155
- <div class="yks_mc_campaign_sent_time_container">
156
- <?php
157
- if ( isset ( $campaign['send_time'] ) ) {
158
- echo '<b>'.__("Sent" , "yikes-inc-easy-mailchimp-extender" ).'</b> '.__("on " , "yikes-inc-easy-mailchimp-extender" ).date( 'D, ' , strtotime($campaign_send_date)).date( 'M j, Y' , strtotime($campaign_send_date)) .__( "at " , "yikes-inc-easy-mailchimp-extender" ) . date( 'g:i a' , strtotime($campaign_send_time) );
159
- } else {
160
- if ( $campaign['status'] == 'sending' && isset( $campaign['type_opts']['last_sent'] ) ) {
161
- echo '<b>'.__( "Recurring Campaign" , "yikes-inc-easy-mailchimp-extender" ).'</b>';
162
- } else {
163
- echo '<b>'.__( "Not Yet Sent" , "yikes-inc-easy-mailchimp-extender" ).'</b>';
164
- }
165
- }
166
- ?>
167
- </div>
168
- </td>
169
- <!-- column 2 -->
170
- <td>
171
- <?php if ( $campaign_type != 'rss' ) { ?>
172
- <div class="yks_campaign_report_click_data" <?php if ( $campaign_type != 'rss' && !isset( $campaign['send_time'] ) || $campaign_type == 'rss' && $campaign['type_opts']['last_sent'] == '' ) { ?> style="opacity:.55;" <?php } ?> >
173
- <span class="campaign_summary_data"><?php echo $total_emails_sent . '<br />'; if ( $total_emails_sent == 1 ) { echo __( ' Subscriber' , 'yikes-inc-easy-mailchimp-extender' ); } else { echo __( ' Subscribers' , 'yikes-inc-easy-mailchimp-extender' ); } ?></span>
174
- <span class="campaign_summary_data"><span class="original_view"><?php echo $campaign_unique_opens . ' <br />'; if ( $campaign_unique_opens == 1 ) { echo __( ' Open', 'yikes-inc-easy-mailchimp-extender' ); } else { echo __( ' Opens' , 'yikes-inc-easy-mailchimp-extender' ); } ?></span><span class="hover_view"><?php echo $campaign_open_percentage . ' <br />'.__(' Opens' , 'yikes-inc-easy-mailchimp-extender' ); ?></span></span>
175
- <span class="campaign_summary_data"><span class="original_view"><?php echo $campaign_clicks . ' <br />'; if ( $campaign_clicks == 1 ) { echo __( ' Click', 'yikes-inc-easy-mailchimp-extender' ); } else { echo __( ' Clicks', 'yikes-inc-easy-mailchimp-extender' ); } ?></span><span class="hover_view"><?php echo $user_click_percentage . ' <br />'.__( ' Clicks', 'yikes-inc-easy-mailchimp-extender' ); ?></span></span>
176
- </div>
177
- <?php } else { ?>
178
- <div class="yks_campaign_report_click_data" <?php if ( $campaign_type != 'rss' && !isset( $campaign['send_time'] ) || $campaign_type == 'rss' && $campaign['type_opts']['last_sent'] == '' ) { ?> style="opacity:.55;" <?php } ?> >
179
- <span class="campaign_summary_data <?php echo $campaign['id']; ?>_total_campaign_sent"><?php echo $total_emails_sent . ' <br />'.__( ' Campaigns Sent', 'yikes-inc-easy-mailchimp-extender' ); ?></span>
180
- <span class="campaign_summary_data <?php echo $campaign['id']; ?>_total_campaign_opened"><span class=""><?php echo $campaign_unique_opens . ' <br />'.__( ' Opens', 'yikes-inc-easy-mailchimp-extender' ); ?></span></span>
181
- <span class="campaign_summary_data <?php echo $campaign['id']; ?>_total_campaign_clicked"><span class=""><?php echo $campaign_clicks . ' <br />' .__( ' Clicks', 'yikes-inc-easy-mailchimp-extender' ); ?></span></span>
182
- </div>
183
- <?php } ?>
184
- </td>
185
- <!-- column 3 // view report -->
186
- <td>
187
- <?php if ( isset ( $campaign['send_time'] ) ) { ?>
188
- <input type="submit" value="View Report" alt="<?php echo $campaign_id; ?>" title="<?php echo $campaign['title']; ?>" class="yks-mc-view-report-button green-flat-button">
189
- <?php } else if ( !isset ( $campaign['send_time'] ) && $campaign_type == 'rss' && $campaign['type_opts']['last_sent'] != '' ) { ?>
190
- <input type="submit" value="RSS" alt="<?php echo $campaign_id; ?>" title="<?php echo $campaign['title']; ?>" class="yks-mc-view-report-button orange-flat-button rss_parent_button">
191
- <?php } else { ?>
192
- <input disabled="disabled" type="submit" value="<?php _e( 'Not Yet Sent', 'yikes-inc-easy-mailchimp-extender' ); ?>" alt="<?php echo $campaign_id; ?>" title="<?php echo $campaign['title']; ?>" class="yks-mc-view-report-button green-flat-button">
193
- <?php } ?>
194
- <input type="hidden" class="yks-mc-campaign-email-subject" value="<?php echo $campaign_email_subject; ?>" />
195
- <input type="hidden" class="yks-mc-campaign-send-time" value="<?php echo $campaign_send_time; ?>" />
196
- <input type="hidden" class="yks-mc-campaign-send-date" value="<?php echo $campaign_send_date; ?>" />
197
- <input type="hidden" class="yks-mc-campaign-web-id" value="<?php echo $campaign_web_id; ?>" />
198
- <input type="hidden" class="yks-mc-campaign-view-email-link" value="<?php echo $preview_campaign_link; ?>?TB_iframe=true&width=900&height=650" />
199
- </td>
200
- </tr>
201
- <tr>
202
- <td>&nbsp;</td>
203
- <td>&nbsp;</td>
204
- </tr>
205
- <?php
206
- // place all our child elements below the parent,
207
- // so we can use jQuery expand+collapse
208
- // to do
209
- // fix child campaign id's, sent time, send date etc. etc.
210
- // re-create the variables inside this foreach loop and condiitonal
211
- // nest, and hide children
212
- // update RSS campaign button to expand elements below etc.
213
- if ( !empty( $child_campaign_array ) ) {
214
-
215
- foreach ($child_campaign_array as $child_campaign ) {
216
-
217
- if ( $child_campaign['parent_id'] == $campaign['id'] ) {
218
- // javascript loop to get how many campaigns were sent
219
- // for a given group of campaign
220
-
221
- $send_time_explosion = explode( " " , $child_campaign['send_time'] );
222
- $campaign_send_time = $send_time_explosion[1];
223
-
224
- $send_time_explode = explode( ":" , $campaign_send_time );
225
- $campaign_send_time = ( $send_time_explode[0] + $timezone_offset ).':'.$send_time_explode[1];
226
-
227
- $campaign_send_date = $send_time_explosion[0];
228
- $total_emails_sent = $child_campaign['emails_sent'];
229
- $campaign_unique_opens = $child_campaign['summary']['unique_opens'];
230
- $campaign_clicks = $child_campaign['summary']['users_who_clicked'];
231
- $campaign_web_id = $child_campaign['web_id'];
232
- $campaign_open_percentage = round((float)($campaign_unique_opens/$total_emails_sent) * 100 ) . '%';
233
- $user_click_percentage = round((float)($campaign_clicks/$total_emails_sent) * 100 ) . '%';
234
- ?>
235
- <tr class="single_report_row <?php if ( $child_campaign['is_child'] == 1 ) { echo $child_campaign['parent_id'].'_child_report_row yks_mc_child_report'; } ?>">
236
- <td style="text-align:center;">
237
- <div class="dashicons dashicons-minus"></div>
238
- </td>
239
- <!-- column 1 -->
240
- <td>
241
- <?php if ( isset ( $child_campaign['send_time'] ) ) { ?>
242
- <a class="yks_campaign_report_link yks-mc-view-report-button" href="#" onclick="return false;" alt="<?php echo $child_campaign['id']; ?>" title="<?php echo $child_campaign['title']; ?>"><?php echo '--'.$child_campaign['title']; ?></a>
243
- <?php } else {
244
- echo '<span class="yks_campaign_report_disabled_link">'.$child_campaign['title'].'</span>';
245
- } ?>
246
- <div class="yks_mc_campaign_sent_time_container">
247
- <?php
248
- if ( isset ( $child_campaign['send_time'] ) ) {
249
- echo '<b>' . __( 'Sent', 'yikes-inc-easy-mailchimp-extender' ) . '</b> on '.date( 'D, ' , strtotime($campaign_send_date)).date( 'M j, Y' , strtotime($campaign_send_date)) . ' at ' . date( 'g:i a' , strtotime($campaign_send_time) );
250
- } else {
251
- if ( $child_campaign['status'] == 'sending' ) {
252
- echo '<b>' . __( 'Recurring Campaign', 'yikes-inc-easy-mailchimp-extender' ) . '</b>';
253
- } else {
254
- echo '<b>' . __( 'Not Yet Sent', 'yikes-inc-easy-mailchimp-extender' ) . '</b>';
255
- }
256
- }
257
- ?>
258
- </div>
259
- </td>
260
- <!-- column 2 -->
261
- <td>
262
- <div class="yks_campaign_report_click_data" <?php if ( !isset ( $child_campaign['send_time'] ) ) { ?> style="opacity:.55;" <?php } ?> >
263
- <span class="campaign_summary_data"><?php echo $total_emails_sent . '<br />'; if ( $total_emails_sent == 1 ) { echo __( ' Subscriber', 'yikes-inc-easy-mailchimp-extender' ); } else { echo __( ' Subscribers', 'yikes-inc-easy-mailchimp-extender' ); } ?></span>
264
- <span class="campaign_summary_data"><span class="original_view"><?php echo $campaign_unique_opens . ' <br />'; if ( $campaign_unique_opens == 1 ) { echo __( ' Open', 'yikes-inc-easy-mailchimp-extender' ); } else { echo __( ' Opens', 'yikes-inc-easy-mailchimp-extender' ); } ?></span><span class="hover_view"><?php echo $campaign_open_percentage . ' <br />' . __ ( ' Opens', 'yikes-inc-easy-mailchimp-extender' ); ?></span></span>
265
- <span class="campaign_summary_data"><span class="original_view"><?php echo $campaign_clicks . ' <br />'; if ( $campaign_clicks == 1 ) { echo __( ' Click', 'yikes-inc-easy-mailchimp-extender' ); } else { echo __( ' Clicks' , 'yikes-inc-easy-mailchimp-extender' ); } ?></span><span class="hover_view"><?php echo $user_click_percentage . ' <br />'. __ ( ' Clicks', 'yikes-inc-easy-mailchimp-extender' ); ?></span></span>
266
- </div>
267
- </td>
268
- <!-- column 3 // view report -->
269
- <td>
270
- <?php if ( isset ( $child_campaign['send_time'] ) ) { ?>
271
- <input type="submit" value="View Report" alt="<?php echo $child_campaign['id']; ?>" title="<?php echo $child_campaign['title']; ?>" class="yks-mc-view-report-button green-flat-button">
272
- <?php } else if ( !isset ( $child_campaign['send_time'] ) && $campaign_type == 'rss' ) { ?>
273
- <input disabled="disabled" type="submit" value="RSS" alt="<?php echo $campaign_id; ?>" title="<?php echo $child_campaign['title']; ?>" class="yks-mc-view-report-button green-flat-button">
274
- <?php } else { ?>
275
- <input disabled="disabled" type="submit" value="<?php _e( 'Not Yet Sent', 'yikes-inc-easy-mailchimp-extender' ); ?>" alt="<?php echo $campaign_id; ?>" title="<?php echo $child_campaign['title']; ?>" class="yks-mc-view-report-button green-flat-button">
276
- <?php } ?>
277
- <input type="hidden" class="yks-mc-campaign-email-subject" value="<?php echo $campaign_email_subject; ?>" />
278
- <input type="hidden" class="yks-mc-campaign-send-time" value="<?php echo $campaign_send_time; ?>" />
279
- <input type="hidden" class="yks-mc-campaign-send-date" value="<?php echo $campaign_send_date; ?>" />
280
- <input type="hidden" class="yks-mc-campaign-web-id" value="<?php echo $campaign_web_id; ?>" />
281
- <input type="hidden" class="yks-mc-campaign-view-email-link" value="<?php echo $preview_campaign_link; ?>?TB_iframe=true&width=900&height=650" />
282
- </td>
283
- </tr>
284
- <tr>
285
- <td>&nbsp;</td>
286
- <td>&nbsp;</td>
287
- </tr>
288
- <?php
289
- }
290
- }
291
- }
292
- } else {
293
- // push the child campaign into an array
294
- $child_campaign_array[] = $campaign;
295
- }
296
- }
297
- // if the user hasn't sent any campaigns before
298
- } else {
299
- ?>
300
- <tr class="single_report_row">
301
- <td style="width:100%;text-align:center !important;">
302
- <h2 class="no_data_found"><?php _e( "It looks like you haven't sent any campaigns yet." , "yikes-inc-easy-mailchimp-extender" ); ?></h2>
303
- </td>
304
- </tr>
305
- <?php
306
- }
307
- ?>
308
- </tbody>
309
- </table>
310
-
311
- <!-- jQuery script to count and populate the necessary parent fields for RSS feed campaigns -->
312
- <script>
313
- jQuery(document).ready(function() {
314
-
315
- var i = 0;
316
-
317
- jQuery('.rss_single_report_row').each(function() {
318
-
319
- var campaign_id = jQuery(this).find('.yks-mc-view-report-button').attr('alt');
320
- var campaign_length = jQuery('.'+campaign_id+'_child_report_row').length;
321
-
322
- // set the number of sent campaigns
323
- jQuery('.'+campaign_id+'_total_campaign_sent').html(campaign_length+'<br /> <?php _e("Campaigns Sent", "yikes-inc-easy-mailchimp-extender" ); ?>');
324
-
325
- var opens_sum = [];
326
-
327
- var clicks_sum = [];
328
-
329
- // loop over the children and add up the total number of opens and clicks
330
- jQuery('.'+campaign_id+'_child_report_row').each(function() {
331
-
332
- var total_opens = jQuery(this).find('.yks_campaign_report_click_data').find('span:nth-child(2)').find('.original_view').text().replace( '<?php _e(" Opens" , "yikes-inc-easy-mailchimp-extender"); ?>' , '' ).replace( '<?php _e(" Open" , "yikes-inc-easy-mailchimp-extender"); ?>' , '' );
333
- var total_clicks = jQuery(this).find('.yks_campaign_report_click_data').find('span:nth-child(3)').find('.original_view').text().replace( '<?php _e(" Clicks" , "yikes-inc-easy-mailchimp-extender"); ?>' , '' ).replace( '<?php _e(" Click" , "yikes-inc-easy-mailchimp-extender"); ?>' , '' );
334
-
335
- // testing stored variables
336
- /*
337
- console.log('The Campaign ID is : '+campaign_id+' and this childs open count is..... '+total_opens);
338
-
339
- console.log('The Campaign ID is : '+campaign_id+' and this childs click count is..... '+total_clicks);
340
- */
341
-
342
- opens_sum.push(total_opens);
343
-
344
- clicks_sum.push(total_clicks);
345
-
346
- });
347
-
348
- /*
349
- console.log('The opens sum array is : '+opens_sum);
350
- console.log('The clicks sum array is : '+clicks_sum);
351
- */
352
-
353
- // calculating our total RSS campaign opens,
354
- // for all campaigns sent
355
- var campaign_total_opens = 0;
356
- for (var i = 0; i < opens_sum.length; i++) {
357
- campaign_total_opens += opens_sum[i] << 0;
358
- }
359
-
360
- // calculating our total RSS campaign clicks,
361
- // for all campaigns sent
362
- var campaign_total_clicks = 0;
363
- for (var i = 0; i < clicks_sum.length; i++) {
364
- campaign_total_clicks += clicks_sum[i] << 0;
365
- }
366
-
367
-
368
- // set the number of sent campaigns
369
- jQuery('.'+campaign_id+'_total_campaign_opened').html(campaign_total_opens+'<br /><?php _e( "Total Opens" , "yikes-inc-easy-mailchimp-extender" ); ?>');
370
- jQuery('.'+campaign_id+'_total_campaign_clicked').html(campaign_total_clicks+'<br /><?php _e( "Total Clicks" , "yikes-inc-easy-mailchimp-extender" ); ?>');
371
- // console.log(value['total']);
372
-
373
- // set the number of total campaign opens
374
-
375
- // set the number of total campaign clicks
376
- i++;
377
- });
378
-
379
- });
380
  </script>
1
+ <!--
2
+ *
3
+ Translation for Clicks , Click , Opens, and Opens need to be re-done
4
+ *
5
+ -->
6
+ <style>
7
+ /* #Green Flat Button
8
+ ==================================================*/
9
+ .green-flat-button {
10
+ position: relative;
11
+ vertical-align: top;
12
+ width: 70%;
13
+ height: 45px;
14
+ padding: 0;
15
+ font-size: 16px;
16
+ color: white;
17
+ text-align: center;
18
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
19
+ background: #27ae60;
20
+ border: 0;
21
+ border-bottom: 2px solid #219d55;
22
+ cursor: pointer;
23
+ -webkit-box-shadow: inset 0 -2px #219d55;
24
+ box-shadow: inset 0 -2px #219d55;
25
+ min-width: 125px;
26
+ max-width: 125px;
27
+ }
28
+ .green-flat-button:active {
29
+ top: 1px;
30
+ outline: none;
31
+ -webkit-box-shadow: none;
32
+ box-shadow: none;
33
+ }
34
+ /* #Orange Flat Button
35
+ ==================================================*/
36
+ .orange-flat-button {
37
+ position: relative;
38
+ vertical-align: top;
39
+ width: 70%;
40
+ height: 45px;
41
+ padding: 0;
42
+ font-size: 16px;
43
+ color: white;
44
+ text-align: center;
45
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
46
+ background: #f39c12;
47
+ border: 0;
48
+ border-bottom: 2px solid #e8930c;
49
+ cursor: pointer;
50
+ -webkit-box-shadow: inset 0 -2px #e8930c;
51
+ box-shadow: inset 0 -2px #e8930c;
52
+ min-width: 125px;
53
+ max-width: 125px;
54
+ }
55
+ .orange-flat-button:active {
56
+ top: 1px;
57
+ outline: none;
58
+ -webkit-box-shadow: none;
59
+ box-shadow: none;
60
+ }
61
+ </style>
62
+
63
+ <script type="text/javascript">
64
+ // switch out opens, views etc on hover
65
+ jQuery(document).ready(function() {
66
+
67
+ jQuery('.yks_campaign_report_click_data').mouseenter(function() {
68
+ jQuery(this).find('.original_view').hide();
69
+ jQuery(this).find('.hover_view').show();
70
+ });
71
+ jQuery('.yks_campaign_report_click_data').mouseleave(function() {
72
+ jQuery(this).find('.original_view').show();
73
+ jQuery(this).find('.hover_view').hide();
74
+ });
75
+
76
+ // display the rss feed children
77
+ jQuery('.rss_parent_button').click(function() {
78
+
79
+ var campaign_id = jQuery(this).attr('alt');
80
+ jQuery('.'+campaign_id+'_child_report_row').stop().fadeToggle();
81
+ jQuery('.'+campaign_id+'_child_report_row').next().stop().fadeToggle();
82
+
83
+ return false;
84
+ });
85
+
86
+
87
+ });
88
+ </script>
89
+ <?php
90
+ // print campaign data for testing purposes
91
+ // print_r($resp);
92
+ echo '<h2>'.__('Previous Campaigns' , 'yikes-inc-easy-mailchimp-extender' ). '</h2>';
93
+ $campaign_data = $resp['data'];
94
+ $campaign_children_array = array();
95
+ $timezone_offset = get_option('gmt_offset');
96
+ echo '<hr />';
97
+
98
+ // print_r($campaign_data);
99
+
100
+ // view link thickbox url
101
+ // echo $campaign['archive_url']; class="thickbox
102
+ ?>
103
+ <table id="yks-admin-campaign-stats-table">
104
+ <tbody>
105
+ <?php
106
+ // loop over campaign data, and display it much in the same way MailChimp
107
+ if ( !empty( $campaign_data ) ) {
108
+
109
+ $child_campaign_array = array();
110
+
111
+ foreach ( $campaign_data as $campaign ) {
112
+ // Create our variables for the loop
113
+ // create our sent time variables
114
+ $campaign_type = $campaign['type'];
115
+
116
+ $campaign_type_image = '<img src="' . plugins_url().'/yikes-inc-easy-mailchimp-extender/images/stats-icons/'.$campaign_type.'_icon.png' . '" alt="'.$campaign_type.'" class="'.$campaign_type.' image" />';
117
+
118
+ $campaign_id = $campaign['id'];
119
+ $preview_campaign_link = $campaign['archive_url'];
120
+ $total_emails_sent = $campaign['emails_sent'];
121
+ $campaign_email_subject = $campaign['subject'];
122
+ if ( isset($campaign['send_time'] ) && $campaign['send_time'] != '' ) {
123
+ $send_time_explosion = explode( " " , $campaign['send_time'] );
124
+ $send_time_explode = explode( ":" , $send_time_explosion[1] );
125
+ $campaign_send_time = ( $send_time_explode[0] + $timezone_offset ).':'.$send_time_explode[1];
126
+ $campaign_send_date = $send_time_explosion[0];
127
+ $campaign_unique_opens = $campaign['summary']['unique_opens'];
128
+ $campaign_clicks = $campaign['summary']['users_who_clicked'];
129
+ $campaign_web_id = $campaign['web_id'];
130
+ $campaign_open_percentage = round((float)($campaign_unique_opens/$total_emails_sent) * 100 ) . '%';
131
+ $user_click_percentage = round((float)($campaign_clicks/$total_emails_sent) * 100 ) . '%';
132
+ } else {
133
+ $campaign_send_time = '';
134
+ $campaign_send_date = '<strong>Not Sent</strong>';
135
+ $campaign_unique_opens = '0';
136
+ $campaign_clicks = '0';
137
+ $campaign_web_id = '-';
138
+ $campaign_open_percentage ='0 %';
139
+ $user_click_percentage = '0 %';
140
+ }
141
+
142
+ if ( $campaign['is_child'] != 1 ) {
143
+ ?>
144
+ <tr class="single_report_row <?php if ( $campaign_type == 'rss' ) { ?>rss_single_report_row <?php } ?>">
145
+ <td <?php if ( !isset ( $campaign['send_time'] ) && !isset( $campaign['type_opts']['last_sent'] ) ) { ?> style="opacity:.25;" <?php } ?>>
146
+ <?php echo $campaign_type_image; ?>
147
+ </td>
148
+ <!-- column 1 -->
149
+ <td>
150
+ <?php if ( isset ( $campaign['send_time'] ) ) { ?>
151
+ <a class="yks_campaign_report_link yks-mc-view-report-button" href="#" onclick="return false;" alt="<?php echo $campaign_id; ?>" title="<?php echo $campaign['title']; ?>"><?php echo $campaign['title']; ?></a>
152
+ <?php } else {
153
+ echo '<span class="yks_campaign_report_disabled_link">'.$campaign['title'].'</span>';
154
+ } ?>
155
+ <div class="yks_mc_campaign_sent_time_container">
156
+ <?php
157
+ if ( isset ( $campaign['send_time'] ) ) {
158
+ echo '<b>'.__("Sent" , "yikes-inc-easy-mailchimp-extender" ).'</b> '.__("on " , "yikes-inc-easy-mailchimp-extender" ).date( 'D, ' , strtotime($campaign_send_date)).date( 'M j, Y' , strtotime($campaign_send_date)) .__( " at " , "yikes-inc-easy-mailchimp-extender" ) . date( 'g:i a' , strtotime($campaign_send_time) );
159
+ } else {
160
+ if ( $campaign['status'] == 'sending' && isset( $campaign['type_opts']['last_sent'] ) ) {
161
+ echo '<b>'.__( "Recurring Campaign" , "yikes-inc-easy-mailchimp-extender" ).'</b>';
162
+ } else {
163
+ echo '<b>'.__( "Not Yet Sent" , "yikes-inc-easy-mailchimp-extender" ).'</b>';
164
+ }
165
+ }
166
+ ?>
167
+ </div>
168
+ </td>
169
+ <!-- column 2 -->
170
+ <td>
171
+ <?php if ( $campaign_type != 'rss' ) { ?>
172
+ <div class="yks_campaign_report_click_data" <?php if ( $campaign_type != 'rss' && !isset( $campaign['send_time'] ) || $campaign_type == 'rss' && $campaign['type_opts']['last_sent'] == '' ) { ?> style="opacity:.55;" <?php } ?> >
173
+ <span class="campaign_summary_data"><?php echo $total_emails_sent . '<br />'; if ( $total_emails_sent == 1 ) { echo __( ' Subscriber' , 'yikes-inc-easy-mailchimp-extender' ); } else { echo __( ' Subscribers' , 'yikes-inc-easy-mailchimp-extender' ); } ?></span>
174
+ <span class="campaign_summary_data"><span class="original_view"><?php echo $campaign_unique_opens . ' <br />'; if ( $campaign_unique_opens == 1 ) { echo __( ' Open', 'yikes-inc-easy-mailchimp-extender' ); } else { echo __( ' Opens' , 'yikes-inc-easy-mailchimp-extender' ); } ?></span><span class="hover_view"><?php echo $campaign_open_percentage . ' <br />'.__(' Opens' , 'yikes-inc-easy-mailchimp-extender' ); ?></span></span>
175
+ <span class="campaign_summary_data"><span class="original_view"><?php echo $campaign_clicks . ' <br />'; if ( $campaign_clicks == 1 ) { echo __( ' Click', 'yikes-inc-easy-mailchimp-extender' ); } else { echo __( ' Clicks', 'yikes-inc-easy-mailchimp-extender' ); } ?></span><span class="hover_view"><?php echo $user_click_percentage . ' <br />'.__( ' Clicks', 'yikes-inc-easy-mailchimp-extender' ); ?></span></span>
176
+ </div>
177
+ <?php } else { ?>
178
+ <div class="yks_campaign_report_click_data" <?php if ( $campaign_type != 'rss' && !isset( $campaign['send_time'] ) || $campaign_type == 'rss' && $campaign['type_opts']['last_sent'] == '' ) { ?> style="opacity:.55;" <?php } ?> >
179
+ <span class="campaign_summary_data <?php echo $campaign['id']; ?>_total_campaign_sent"><?php echo $total_emails_sent . ' <br />'.__( ' Campaigns Sent', 'yikes-inc-easy-mailchimp-extender' ); ?></span>
180
+ <span class="campaign_summary_data <?php echo $campaign['id']; ?>_total_campaign_opened"><span class=""><?php echo $campaign_unique_opens . ' <br />'.__( ' Opens', 'yikes-inc-easy-mailchimp-extender' ); ?></span></span>
181
+ <span class="campaign_summary_data <?php echo $campaign['id']; ?>_total_campaign_clicked"><span class=""><?php echo $campaign_clicks . ' <br />' .__( ' Clicks', 'yikes-inc-easy-mailchimp-extender' ); ?></span></span>
182
+ </div>
183
+ <?php } ?>
184
+ </td>
185
+ <!-- column 3 // view report -->
186
+ <td>
187
+ <?php if ( isset ( $campaign['send_time'] ) ) { ?>
188
+ <input type="submit" value="View Report" alt="<?php echo $campaign_id; ?>" title="<?php echo $campaign['title']; ?>" class="yks-mc-view-report-button green-flat-button">
189
+ <?php } else if ( !isset ( $campaign['send_time'] ) && $campaign_type == 'rss' && $campaign['type_opts']['last_sent'] != '' ) { ?>
190
+ <input type="submit" value="RSS" alt="<?php echo $campaign_id; ?>" title="<?php echo $campaign['title']; ?>" class="yks-mc-view-report-button orange-flat-button rss_parent_button">
191
+ <?php } else { ?>
192
+ <input disabled="disabled" type="submit" value="<?php _e( 'Not Yet Sent', 'yikes-inc-easy-mailchimp-extender' ); ?>" alt="<?php echo $campaign_id; ?>" title="<?php echo $campaign['title']; ?>" class="yks-mc-view-report-button green-flat-button">
193
+ <?php } ?>
194
+ <input type="hidden" class="yks-mc-campaign-email-subject" value="<?php echo $campaign_email_subject; ?>" />
195
+ <input type="hidden" class="yks-mc-campaign-send-time" value="<?php echo $campaign_send_time; ?>" />
196
+ <input type="hidden" class="yks-mc-campaign-send-date" value="<?php echo $campaign_send_date; ?>" />
197
+ <input type="hidden" class="yks-mc-campaign-web-id" value="<?php echo $campaign_web_id; ?>" />
198
+ <input type="hidden" class="yks-mc-campaign-view-email-link" value="<?php echo $preview_campaign_link; ?>?TB_iframe=true&width=900&height=650" />
199
+ </td>
200
+ </tr>
201
+ <tr>
202
+ <td>&nbsp;</td>
203
+ <td>&nbsp;</td>
204
+ </tr>
205
+ <?php
206
+ // place all our child elements below the parent,
207
+ // so we can use jQuery expand+collapse
208
+ // to do
209
+ // fix child campaign id's, sent time, send date etc. etc.
210
+ // re-create the variables inside this foreach loop and condiitonal
211
+ // nest, and hide children
212
+ // update RSS campaign button to expand elements below etc.
213
+ if ( !empty( $child_campaign_array ) ) {
214
+
215
+ foreach ($child_campaign_array as $child_campaign ) {
216
+
217
+ if ( $child_campaign['parent_id'] == $campaign['id'] ) {
218
+ // javascript loop to get how many campaigns were sent
219
+ // for a given group of campaign
220
+
221
+ $send_time_explosion = explode( " " , $child_campaign['send_time'] );
222
+ $campaign_send_time = $send_time_explosion[1];
223
+
224
+ $send_time_explode = explode( ":" , $campaign_send_time );
225
+ $campaign_send_time = ( $send_time_explode[0] + $timezone_offset ).':'.$send_time_explode[1];
226
+
227
+ $campaign_send_date = $send_time_explosion[0];
228
+ $total_emails_sent = $child_campaign['emails_sent'];
229
+ $campaign_unique_opens = $child_campaign['summary']['unique_opens'];
230
+ $campaign_clicks = $child_campaign['summary']['users_who_clicked'];
231
+ $campaign_web_id = $child_campaign['web_id'];
232
+ $campaign_open_percentage = round((float)($campaign_unique_opens/$total_emails_sent) * 100 ) . '%';
233
+ $user_click_percentage = round((float)($campaign_clicks/$total_emails_sent) * 100 ) . '%';
234
+ ?>
235
+ <tr class="single_report_row <?php if ( $child_campaign['is_child'] == 1 ) { echo $child_campaign['parent_id'].'_child_report_row yks_mc_child_report'; } ?>">
236
+ <td style="text-align:center;">
237
+ <div class="dashicons dashicons-minus"></div>
238
+ </td>
239
+ <!-- column 1 -->
240
+ <td>
241
+ <?php if ( isset ( $child_campaign['send_time'] ) ) { ?>
242
+ <a class="yks_campaign_report_link yks-mc-view-report-button" href="#" onclick="return false;" alt="<?php echo $child_campaign['id']; ?>" title="<?php echo $child_campaign['title']; ?>"><?php echo '--'.$child_campaign['title']; ?></a>
243
+ <?php } else {
244
+ echo '<span class="yks_campaign_report_disabled_link">'.$child_campaign['title'].'</span>';
245
+ } ?>
246
+ <div class="yks_mc_campaign_sent_time_container">
247
+ <?php
248
+ if ( isset ( $child_campaign['send_time'] ) ) {
249
+ echo '<b>' . __( 'Sent', 'yikes-inc-easy-mailchimp-extender' ) . '</b> on '.date( 'D, ' , strtotime($campaign_send_date)).date( 'M j, Y' , strtotime($campaign_send_date)) . ' at ' . date( 'g:i a' , strtotime($campaign_send_time) );
250
+ } else {
251
+ if ( $child_campaign['status'] == 'sending' ) {
252
+ echo '<b>' . __( 'Recurring Campaign', 'yikes-inc-easy-mailchimp-extender' ) . '</b>';
253
+ } else {
254
+ echo '<b>' . __( 'Not Yet Sent', 'yikes-inc-easy-mailchimp-extender' ) . '</b>';
255
+ }
256
+ }
257
+ ?>
258
+ </div>
259
+ </td>
260
+ <!-- column 2 -->
261
+ <td>
262
+ <div class="yks_campaign_report_click_data" <?php if ( !isset ( $child_campaign['send_time'] ) ) { ?> style="opacity:.55;" <?php } ?> >
263
+ <span class="campaign_summary_data"><?php echo $total_emails_sent . '<br />'; if ( $total_emails_sent == 1 ) { echo __( ' Subscriber', 'yikes-inc-easy-mailchimp-extender' ); } else { echo __( ' Subscribers', 'yikes-inc-easy-mailchimp-extender' ); } ?></span>
264
+ <span class="campaign_summary_data"><span class="original_view"><?php echo $campaign_unique_opens . ' <br />'; if ( $campaign_unique_opens == 1 ) { echo __( ' Open', 'yikes-inc-easy-mailchimp-extender' ); } else { echo __( ' Opens', 'yikes-inc-easy-mailchimp-extender' ); } ?></span><span class="hover_view"><?php echo $campaign_open_percentage . ' <br />' . __ ( ' Opens', 'yikes-inc-easy-mailchimp-extender' ); ?></span></span>
265
+ <span class="campaign_summary_data"><span class="original_view"><?php echo $campaign_clicks . ' <br />'; if ( $campaign_clicks == 1 ) { echo __( ' Click', 'yikes-inc-easy-mailchimp-extender' ); } else { echo __( ' Clicks' , 'yikes-inc-easy-mailchimp-extender' ); } ?></span><span class="hover_view"><?php echo $user_click_percentage . ' <br />'. __ ( ' Clicks', 'yikes-inc-easy-mailchimp-extender' ); ?></span></span>
266
+ </div>
267
+ </td>
268
+ <!-- column 3 // view report -->
269
+ <td>
270
+ <?php if ( isset ( $child_campaign['send_time'] ) ) { ?>
271
+ <input type="submit" value="View Report" alt="<?php echo $child_campaign['id']; ?>" title="<?php echo $child_campaign['title']; ?>" class="yks-mc-view-report-button green-flat-button">
272
+ <?php } else if ( !isset ( $child_campaign['send_time'] ) && $campaign_type == 'rss' ) { ?>
273
+ <input disabled="disabled" type="submit" value="RSS" alt="<?php echo $campaign_id; ?>" title="<?php echo $child_campaign['title']; ?>" class="yks-mc-view-report-button green-flat-button">
274
+ <?php } else { ?>
275
+ <input disabled="disabled" type="submit" value="<?php _e( 'Not Yet Sent', 'yikes-inc-easy-mailchimp-extender' ); ?>" alt="<?php echo $campaign_id; ?>" title="<?php echo $child_campaign['title']; ?>" class="yks-mc-view-report-button green-flat-button">
276
+ <?php } ?>
277
+ <input type="hidden" class="yks-mc-campaign-email-subject" value="<?php echo $campaign_email_subject; ?>" />
278
+ <input type="hidden" class="yks-mc-campaign-send-time" value="<?php echo $campaign_send_time; ?>" />
279
+ <input type="hidden" class="yks-mc-campaign-send-date" value="<?php echo $campaign_send_date; ?>" />
280
+ <input type="hidden" class="yks-mc-campaign-web-id" value="<?php echo $campaign_web_id; ?>" />
281
+ <input type="hidden" class="yks-mc-campaign-view-email-link" value="<?php echo $preview_campaign_link; ?>?TB_iframe=true&width=900&height=650" />
282
+ </td>
283
+ </tr>
284
+ <tr>
285
+ <td>&nbsp;</td>
286
+ <td>&nbsp;</td>
287
+ </tr>
288
+ <?php
289
+ }
290
+ }
291
+ }
292
+ } else {
293
+ // push the child campaign into an array
294
+ $child_campaign_array[] = $campaign;
295
+ }
296
+ }
297
+ // if the user hasn't sent any campaigns before
298
+ } else {
299
+ ?>
300
+ <tr class="single_report_row">
301
+ <td style="width:100%;text-align:center !important;">
302
+ <h2 class="no_data_found"><?php _e( "It looks like you haven't sent any campaigns yet." , "yikes-inc-easy-mailchimp-extender" ); ?></h2>
303
+ </td>
304
+ </tr>
305
+ <?php
306
+ }
307
+ ?>
308
+ </tbody>
309
+ </table>
310
+
311
+ <!-- jQuery script to count and populate the necessary parent fields for RSS feed campaigns -->
312
+ <script>
313
+ jQuery(document).ready(function() {
314
+
315
+ var i = 0;
316
+
317
+ jQuery('.rss_single_report_row').each(function() {
318
+
319
+ var campaign_id = jQuery(this).find('.yks-mc-view-report-button').attr('alt');
320
+ var campaign_length = jQuery('.'+campaign_id+'_child_report_row').length;
321
+
322
+ // set the number of sent campaigns
323
+ jQuery('.'+campaign_id+'_total_campaign_sent').html(campaign_length+'<br /> <?php _e("Campaigns Sent", "yikes-inc-easy-mailchimp-extender" ); ?>');
324
+
325
+ var opens_sum = [];
326
+
327
+ var clicks_sum = [];
328
+
329
+ // loop over the children and add up the total number of opens and clicks
330
+ jQuery('.'+campaign_id+'_child_report_row').each(function() {
331
+
332
+ var total_opens = jQuery(this).find('.yks_campaign_report_click_data').find('span:nth-child(2)').find('.original_view').text().replace( '<?php _e(" Opens" , "yikes-inc-easy-mailchimp-extender"); ?>' , '' ).replace( '<?php _e(" Open" , "yikes-inc-easy-mailchimp-extender"); ?>' , '' );
333
+ var total_clicks = jQuery(this).find('.yks_campaign_report_click_data').find('span:nth-child(3)').find('.original_view').text().replace( '<?php _e(" Clicks" , "yikes-inc-easy-mailchimp-extender"); ?>' , '' ).replace( '<?php _e(" Click" , "yikes-inc-easy-mailchimp-extender"); ?>' , '' );
334
+
335
+ // testing stored variables
336
+ /*
337
+ console.log('The Campaign ID is : '+campaign_id+' and this childs open count is..... '+total_opens);
338
+
339
+ console.log('The Campaign ID is : '+campaign_id+' and this childs click count is..... '+total_clicks);
340
+ */
341
+
342
+ opens_sum.push(total_opens);
343
+
344
+ clicks_sum.push(total_clicks);
345
+
346
+ });
347
+
348
+ /*
349
+ console.log('The opens sum array is : '+opens_sum);
350
+ console.log('The clicks sum array is : '+clicks_sum);
351
+ */
352
+
353
+ // calculating our total RSS campaign opens,
354
+ // for all campaigns sent
355
+ var campaign_total_opens = 0;
356
+ for (var i = 0; i < opens_sum.length; i++) {
357
+ campaign_total_opens += opens_sum[i] << 0;
358
+ }
359
+
360
+ // calculating our total RSS campaign clicks,
361
+ // for all campaigns sent
362
+ var campaign_total_clicks = 0;
363
+ for (var i = 0; i < clicks_sum.length; i++) {
364
+ campaign_total_clicks += clicks_sum[i] << 0;
365
+ }
366
+
367
+
368
+ // set the number of sent campaigns
369
+ jQuery('.'+campaign_id+'_total_campaign_opened').html(campaign_total_opens+'<br /><?php _e( "Total Opens" , "yikes-inc-easy-mailchimp-extender" ); ?>');
370
+ jQuery('.'+campaign_id+'_total_campaign_clicked').html(campaign_total_clicks+'<br /><?php _e( "Total Clicks" , "yikes-inc-easy-mailchimp-extender" ); ?>');
371
+ // console.log(value['total']);
372
+
373
+ // set the number of total campaign opens
374
+
375
+ // set the number of total campaign clicks
376
+ i++;
377
+ });
378
+
379
+ });
380
  </script>
templates/mailChimp-list-growth-template.php CHANGED
@@ -1,399 +1,399 @@
1
- <?php
2
-
3
- // setup the Data Variables to apply to our chart
4
- // build our arrays
5
- $data_array = array();
6
- $month_array = array();
7
- $total_subscriber_array = array();
8
- $new_subscriber_array = array();
9
- $optin_subscriber_array = array();
10
-
11
- // loop over and build month array using
12
- // $data_response['month']
13
- /*
14
- foreach ( $resp as $data_response ) {
15
- array_push( $month_array , date( 'M Y' , strtotime( $data_response['month'] ) ) );
16
- }
17
- */
18
- // loop over and build the existing subscriber count array
19
- // using $data_response['existing']
20
-
21
- $i = 0;
22
- foreach ( $resp as $data_response ) {
23
- $data_array[$i]['month'] = strtotime( $data_response['month'] );
24
- $data_array[$i]['existing'] = $data_response['existing'];
25
- $data_array[$i]['imports'] = $data_response['imports'];
26
- $data_array[$i]['optins'] = $data_response['optins'];
27
- /*
28
- array_push( $total_subscriber_array , $data_response['existing'] );
29
- array_push( $new_subscriber_array , $data_response['imports'] );
30
- array_push( $optin_subscriber_array , $data_response['optins'] );
31
- */
32
- $i++;
33
- }
34
-
35
- // sort the array based on the date...
36
- // should be earliest to latest
37
- // asort( $month_strtotime_array );
38
-
39
- array_multisort( $data_array , SORT_ASC );
40
-
41
- foreach ( $data_array as $mc_list_data ) {
42
- $month_array[] = date( 'F Y' , $mc_list_data['month']);
43
- $total_subscriber_array[] = $mc_list_data['existing'];
44
- $new_subscriber_array[] = $mc_list_data['imports'];
45
- $optin_subscriber_array[] = $mc_list_data['optins'];
46
- }
47
-
48
-
49
-
50
- // print_r($month_array);
51
- if ( !empty( $resp ) ) {
52
- ?>
53
- <script type="text/javascript">
54
- // here is our ajax function to reload
55
- // and refresh the stats div, with the new
56
- // list ID that we have selected
57
-
58
-
59
- jQuery(document).ready(function () {
60
-
61
- // clicking on a stats name...
62
- jQuery('.stats_list_name').off().on( 'click' , function() {
63
- var apiKey = '<?php echo $this->optionVal['api-key']; ?>';
64
- // remove the active_button class from all stats buttons
65
- jQuery('.stats_list_name').find('input').removeClass('active_button');
66
-
67
- // re-add the class to the clicked button
68
- // used in the chart title...
69
- jQuery(this).find('input').addClass('active_button');
70
-
71
- // get and store the active parent button,
72
- // which dictates if we query Growth History Stats
73
- // or Campaign Stats
74
- var active_parent_button = jQuery('.active-parent-button').text();
75
-
76
- /** Begin Conditional AJAX **/
77
- // check the active button is Growth History
78
- // if so, query Ajax for Growth History Data
79
- if ( active_parent_button == 'Growth History' ) {
80
- // smooth scroll back to chart
81
- jQuery('html, body').animate({
82
- scrollTop: jQuery(".account-nav-tab").offset().top
83
- }, 350);
84
-
85
- // append our preloader , while we fetch the data from MailChimp
86
- jQuery('.mailChimpStatisticsDiv').html('<img class="mailChimp_get_subscribers_preloader" src="<?php echo admin_url().'/images/wpspin_light.gif'; ?>" alt="preloader" >');
87
- jQuery.ajax({
88
- type: 'POST',
89
- url: ajaxurl,
90
- data: {
91
- action: 'yks_mailchimp_form',
92
- form_action: 'yks_get_growth_data',
93
- api_key: apiKey,
94
- list_id: jQuery(this).attr('alt')
95
- },
96
- dataType: 'html',
97
- success: function(response) {
98
- // reload the chart
99
- jQuery('.mailChimpStatisticsDiv').html('<div>'+response+'</div>');
100
- }
101
- });
102
- // if the active parent button is Campaign Stats,
103
- // we should query for Campaign Stats for the specified List
104
- } else if ( active_parent_button == 'Campaign Stats' ) {
105
- var apiKey = '<?php echo $this->optionVal['api-key']; ?>';
106
- jQuery('.mailChimpStatisticsDiv').html('<img class="mailChimp_get_subscribers_preloader" src="<?php echo admin_url().'/images/wpspin_light.gif'; ?>" alt="preloader" >');
107
- jQuery.ajax({
108
- type: 'POST',
109
- url: ajaxurl,
110
- data: {
111
- action: 'yks_mailchimp_form',
112
- form_action: 'yks_get_campaign_data',
113
- api_key: apiKey,
114
- // campaign_id: jQuery(this).attr('alt')
115
- },
116
- dataType: 'html',
117
- success: function(response) {
118
- // reload the chart
119
- jQuery('.mailChimpStatisticsDiv').html('<div>'+response+'</div>');
120
- }
121
- });
122
- }
123
- });
124
-
125
- jQuery('.campaign-stats-button').off().on( 'click' , function() {
126
- var apiKey = '<?php echo $this->optionVal['api-key']; ?>';
127
- // hide and show the correct divs
128
- if ( jQuery('#interactive_list_items').is(':visible') ) {
129
- // hide the selectable lists
130
- jQuery('#interactive_list_items').hide();
131
- // show our selectable campaigns
132
- jQuery('#interactive_campaigns').show();
133
- }
134
-
135
- // remove active-parent-button class from all elements
136
- jQuery('.statistics-sub-title').each(function() {
137
- jQuery(this).removeClass('active-parent-button');
138
- });
139
- // re-add it to the clicked element
140
- jQuery(this).addClass('active-parent-button');
141
-
142
- // get and store the active parent button,
143
- // which dictates if we query Growth History Stats
144
- // or Campaign Stats
145
- var active_list_button = jQuery('.list_container_for_stats').find('.active_button').text();
146
- // AJAX request to get campaign data
147
- jQuery('.mailChimpStatisticsDiv').html('<img class="mailChimp_get_subscribers_preloader" src="<?php echo admin_url().'/images/wpspin_light.gif'; ?>" alt="preloader" >');
148
- jQuery.ajax({
149
- type: 'POST',
150
- url: ajaxurl,
151
- data: {
152
- action: 'yks_mailchimp_form',
153
- form_action: 'yks_get_campaign_data',
154
- api_key: apiKey,
155
- // campaign_id: jQuery(this).attr('alt')
156
- },
157
- dataType: 'html',
158
- success: function(response) {
159
- // reload the chart
160
- jQuery('.mailChimpStatisticsDiv').html('<div>'+response+'</div>');
161
- }
162
- });
163
-
164
- });
165
-
166
- // Growth History Click
167
- jQuery('.growth-history-button').off().on( 'click' , function() {
168
- var apiKey = '<?php echo $this->optionVal['api-key']; ?>';
169
- // show and hide the correct div's
170
- if ( jQuery('#interactive_campaigns').is(':visible') ) {
171
- // hide the selectable lists
172
- jQuery('#interactive_campaigns').hide();
173
- // show our selectable campaigns
174
- jQuery('#interactive_list_items').show();
175
- }
176
-
177
- // remove active-parent-button class from all elements
178
- jQuery('.statistics-sub-title').each(function() {
179
- jQuery(this).removeClass('active-parent-button');
180
- });
181
- // re-add it to the clicked element
182
- jQuery(this).addClass('active-parent-button');
183
-
184
- // get and store the active parent button,
185
- // which dictates if we query Growth History Stats
186
- // or Campaign Stats
187
- var active_parent_button = jQuery('.active-parent-button').text();
188
-
189
- /** Begin Conditional AJAX **/
190
- // check the active button is Growth History
191
- // if so, query Ajax for Growth History Data
192
- if ( active_parent_button == 'Growth History' ) {
193
- // smooth scroll back to chart
194
- jQuery('html, body').animate({
195
- scrollTop: jQuery(".account-nav-tab").offset().top
196
- }, 350);
197
-
198
- // append our preloader , while we fetch the data from MailChimp
199
- jQuery('.mailChimpStatisticsDiv').html('<img class="mailChimp_get_subscribers_preloader" src="<?php echo admin_url().'/images/wpspin_light.gif'; ?>" alt="preloader" >');
200
- jQuery.ajax({
201
- type: 'POST',
202
- url: ajaxurl,
203
- data: {
204
- action: 'yks_mailchimp_form',
205
- form_action: 'yks_get_growth_data',
206
- api_key: apiKey,
207
- list_id: jQuery('.list_container_for_stats').find('.active_button').attr('alt')
208
- },
209
- dataType: 'html',
210
- success: function(response) {
211
- // reload the chart
212
- jQuery('.mailChimpStatisticsDiv').html('<div>'+response+'</div>');
213
- }
214
- });
215
- // if the active parent button is Campaign Stats,
216
- // we should query for Campaign Stats for the specified List
217
- } else if ( active_parent_button == 'Campaign Stats' ) {
218
- var apiKey = '<?php echo $this->optionVal['api-key']; ?>';
219
- jQuery('.mailChimpStatisticsDiv').html('<img class="mailChimp_get_subscribers_preloader" src="<?php echo admin_url().'/images/wpspin_light.gif'; ?>" alt="preloader" >');
220
- jQuery.ajax({
221
- type: 'POST',
222
- url: ajaxurl,
223
- data: {
224
- action: 'yks_mailchimp_form',
225
- form_action: 'yks_get_campaign_data',
226
- api_key: apiKey,
227
- // campaign_id: jQuery(this).attr('alt')
228
- },
229
- dataType: 'html',
230
- success: function(response) {
231
- // reload the chart
232
- jQuery('.mailChimpStatisticsDiv').html('<div>'+response+'</div>');
233
- }
234
- });
235
- }
236
-
237
- });
238
-
239
-
240
- // Ajax to load in our report data for a specific campaign
241
- // post the data to our get growth list data
242
- jQuery('.mailChimpStatisticsDiv').off().on().delegate( '.yks-mc-view-report-button', 'click' , function() {
243
-
244
- // #mailChimpStatisticsDiv
245
- var campaign_id = jQuery(this).attr('alt');
246
- var campaign_title = jQuery(this).attr('title');
247
- var campaign_subject = jQuery(this).parents('.single_report_row').find('.yks-mc-campaign-email-subject').val();
248
- var campaign_send_date = jQuery(this).parents('.single_report_row').find('.yks-mc-campaign-send-date').val();
249
- var campaign_send_time = jQuery(this).parents('.single_report_row').find('.yks-mc-campaign-send-time').val();
250
- var campaign_view_email_link = jQuery(this).parents('.single_report_row').find('.yks-mc-campaign-view-email-link').val();
251
- var campaign_web_id = jQuery(this).parents('.single_report_row').find('.yks-mc-campaign-web-id').val();
252
- var apiKey = '<?php echo $this->optionVal['api-key']; ?>';
253
-
254
- // hide the parent buttons
255
- jQuery('.statistics-sub-title').hide();
256
-
257
- // ajax request to get our specific campaign report data
258
- jQuery('.mailChimpStatisticsDiv').html('<img class="mailChimp_get_subscribers_preloader" style="padding-top:4em;" src="<?php echo admin_url().'/images/wpspin_light.gif'; ?>" alt="preloader" >');
259
- jQuery.ajax({
260
- type: 'POST',
261
- url: ajaxurl,
262
- data: {
263
- action: 'yks_mailchimp_form',
264
- form_action: 'yks_get_specific_campaign_data',
265
- api_key: apiKey,
266
- campaign_id: campaign_id,
267
- campaign_title: campaign_title,
268
- campaign_subject: campaign_subject ,
269
- campaign_send_date: campaign_send_date,
270
- campaign_send_time: campaign_send_time,
271
- campaign_view_email_link: campaign_view_email_link,
272
- campaign_web_Id: campaign_web_id
273
- },
274
- dataType: 'html',
275
- success: function(response) {
276
- jQuery('.mailChimpStatisticsDiv').html('<div>'+response+'</div>');
277
- }
278
- });
279
-
280
- // append our preloader , while we fetch the data from MailChimp
281
- jQuery.ajax({
282
- type: 'POST',
283
- url: ajaxurl,
284
- data: {
285
- action: 'yks_mailchimp_form',
286
- form_action: 'yks_get_specific_campaign_link_data',
287
- api_key: apiKey,
288
- campaign_id: campaign_id
289
- },
290
- dataType: 'html',
291
- success: function(response) {
292
- // reload the chart
293
- jQuery('#click_tracking_info').html('<div>'+response+'</div>');
294
- },
295
- error: function(response) {
296
- console.log('Error Returned From MailChimp : '+response);
297
- }
298
- });
299
-
300
- // ajax request to get the geo data for opened links
301
- jQuery.ajax({
302
- type: 'POST',
303
- url: ajaxurl,
304
- data: {
305
- action: 'yks_mailchimp_form',
306
- form_action: 'yks_get_campaign_links_geo_opens',
307
- api_key: apiKey,
308
- campaign_id: campaign_id
309
- },
310
- dataType: 'html',
311
- success: function(response) {
312
- jQuery('#geo_data_link_map').html('<div>'+response+'</div>');
313
- }
314
- });
315
-
316
- });
317
-
318
- var chart_title = jQuery('.active_button').val();
319
-
320
- if ( chart_title == '' || chart_title == 'All Lists' ) {
321
- chart_title = 'Account'
322
- } else {
323
- chart_title = chart_title+' List';
324
- }
325
-
326
- // to do - set up other buttons to load different charts
327
-
328
- var chart_description = jQuery('.active_chart_button').text();
329
-
330
- <?php if ( !empty($month_array) ) { ?>
331
-
332
- // Set up the chart
333
-
334
- var chart = new Highcharts.Chart({
335
- chart: {
336
- renderTo: 'overall_account_growth',
337
- type: 'column',
338
- margin: 75,
339
- options3d: {
340
- enabled: true,
341
- alpha: 0,
342
- beta: 0,
343
- depth: 50,
344
- viewDistance: 25
345
- }
346
- },
347
- xAxis: {
348
- // categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
349
- categories: [<?php echo '"' . implode( ' ", "' , $month_array ) .'"'; ?>]
350
- },
351
- title: {
352
- text: chart_title+' Growth'
353
- },
354
- subtitle: {
355
- text: 'subscribers gained by month.'
356
- },
357
- plotOptions: {
358
- column: {
359
- depth: 25
360
- }
361
- },
362
- yAxis: {
363
- title: {
364
- text: 'Subscribers'
365
- }
366
- },
367
- series: [{
368
- // data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]
369
- data: [<?php echo implode( ', ' , $total_subscriber_array ); ?>],
370
- showInLegend: true,
371
- name: "<b><?php _e( 'Total Subscribers' , 'yikes-inc-easy-mailchimp-extender' ); ?></b>",
372
- },
373
- {
374
- data: [<?php echo implode( ', ' , $new_subscriber_array ); ?>],
375
- showInLegend: true,
376
- name: "<b><?php _e( 'Imported Subscribers' , 'yikes-inc-easy-mailchimp-extender' ); ?></b>",
377
- },
378
- {
379
- data: [<?php echo implode( ', ' , $optin_subscriber_array ); ?>],
380
- showInLegend: true,
381
- name: "<b><?php _e( 'Opt-in Subscribers' , 'yikes-inc-easy-mailchimp-extender' ); ?></b>",
382
- }
383
- ],
384
- credits: {
385
- enabled: false
386
- },
387
- });
388
-
389
- <?php } else { ?>
390
- jQuery('.mailChimpStatisticsDiv').html("<div class=no_data_found><?php _e( 'There is no growth data for' , 'yikes-inc-easy-mailchimp-extender' ); ?>"+chart_title+"<?php _e( ' yet' , 'yikes-inc-easy-mailchimp-extender' ); ?></div>");
391
- <?php } ?>
392
-
393
- });
394
- </script>
395
- <?php } else { ?>
396
-
397
- <h2 class="no_data_found" style="width:100%;text-align:center;"><?php _e( "No growth data found yet. Please try again at a later time." , "yikes-inc-easy-mailchimp-extender" ); ?></h2>
398
- <?php } ?>
399
  <div id="overall_account_growth"></div>
1
+ <?php
2
+
3
+ // setup the Data Variables to apply to our chart
4
+ // build our arrays
5
+ $data_array = array();
6
+ $month_array = array();
7
+ $total_subscriber_array = array();
8
+ $new_subscriber_array = array();
9
+ $optin_subscriber_array = array();
10
+
11
+ // loop over and build month array using
12
+ // $data_response['month']
13
+ /*
14
+ foreach ( $resp as $data_response ) {
15
+ array_push( $month_array , date( 'M Y' , strtotime( $data_response['month'] ) ) );
16
+ }
17
+ */
18
+ // loop over and build the existing subscriber count array
19
+ // using $data_response['existing']
20
+
21
+ $i = 0;
22
+ foreach ( $resp as $data_response ) {
23
+ $data_array[$i]['month'] = strtotime( $data_response['month'] );
24
+ $data_array[$i]['existing'] = $data_response['existing'];
25
+ $data_array[$i]['imports'] = $data_response['imports'];
26
+ $data_array[$i]['optins'] = $data_response['optins'];
27
+ /*
28
+ array_push( $total_subscriber_array , $data_response['existing'] );
29
+ array_push( $new_subscriber_array , $data_response['imports'] );
30
+ array_push( $optin_subscriber_array , $data_response['optins'] );
31
+ */
32
+ $i++;
33
+ }
34
+
35
+ // sort the array based on the date...
36
+ // should be earliest to latest
37
+ // asort( $month_strtotime_array );
38
+
39
+ array_multisort( $data_array , SORT_ASC );
40
+
41
+ foreach ( $data_array as $mc_list_data ) {
42
+ $month_array[] = date( 'F Y' , $mc_list_data['month']);
43
+ $total_subscriber_array[] = $mc_list_data['existing'];
44
+ $new_subscriber_array[] = $mc_list_data['imports'];
45
+ $optin_subscriber_array[] = $mc_list_data['optins'];
46
+ }
47
+
48
+
49
+
50
+ // print_r($month_array);
51
+ if ( !empty( $resp ) ) {
52
+ ?>
53
+ <script type="text/javascript">
54
+ // here is our ajax function to reload
55
+ // and refresh the stats div, with the new
56
+ // list ID that we have selected
57
+
58
+
59
+ jQuery(document).ready(function () {
60
+
61
+ // clicking on a stats name...
62
+ jQuery('.stats_list_name').off().on( 'click' , function() {
63
+ var apiKey = '<?php echo $this->optionVal['api-key']; ?>';
64
+ // remove the active_button class from all stats buttons
65
+ jQuery('.stats_list_name').find('input').removeClass('active_button');
66
+
67
+ // re-add the class to the clicked button
68
+ // used in the chart title...
69
+ jQuery(this).find('input').addClass('active_button');
70
+
71
+ // get and store the active parent button,
72
+ // which dictates if we query Growth History Stats
73
+ // or Campaign Stats
74
+ var active_parent_button = jQuery('.active-parent-button').text();
75
+
76
+ /** Begin Conditional AJAX **/
77
+ // check the active button is Growth History
78
+ // if so, query Ajax for Growth History Data
79
+ if ( active_parent_button == 'Growth History' ) {
80
+ // smooth scroll back to chart
81
+ jQuery('html, body').animate({
82
+ scrollTop: jQuery(".account-nav-tab").offset().top
83
+ }, 350);
84
+
85
+ // append our preloader , while we fetch the data from MailChimp
86
+ jQuery('.mailChimpStatisticsDiv').html('<img class="mailChimp_get_subscribers_preloader" src="<?php echo admin_url().'/images/wpspin_light.gif'; ?>" alt="preloader" >');
87
+ jQuery.ajax({
88
+ type: 'POST',
89
+ url: ajaxurl,
90
+ data: {
91
+ action: 'yks_mailchimp_form',
92
+ form_action: 'yks_get_growth_data',
93
+ api_key: apiKey,
94
+ list_id: jQuery(this).attr('alt')
95
+ },
96
+ dataType: 'html',
97
+ success: function(response) {
98
+ // reload the chart
99
+ jQuery('.mailChimpStatisticsDiv').html('<div>'+response+'</div>');
100
+ }
101
+ });
102
+ // if the active parent button is Campaign Stats,
103
+ // we should query for Campaign Stats for the specified List
104
+ } else if ( active_parent_button == 'Campaign Stats' ) {
105
+ var apiKey = '<?php echo $this->optionVal['api-key']; ?>';
106
+ jQuery('.mailChimpStatisticsDiv').html('<img class="mailChimp_get_subscribers_preloader" src="<?php echo admin_url().'/images/wpspin_light.gif'; ?>" alt="preloader" >');
107
+ jQuery.ajax({
108
+ type: 'POST',
109
+ url: ajaxurl,
110
+ data: {
111
+ action: 'yks_mailchimp_form',
112
+ form_action: 'yks_get_campaign_data',
113
+ api_key: apiKey,
114
+ // campaign_id: jQuery(this).attr('alt')
115
+ },
116
+ dataType: 'html',
117
+ success: function(response) {
118
+ // reload the chart
119
+ jQuery('.mailChimpStatisticsDiv').html('<div>'+response+'</div>');
120
+ }
121
+ });
122
+ }
123
+ });
124
+
125
+ jQuery('.campaign-stats-button').off().on( 'click' , function() {
126
+ var apiKey = '<?php echo $this->optionVal['api-key']; ?>';
127
+ // hide and show the correct divs
128
+ if ( jQuery('#interactive_list_items').is(':visible') ) {
129
+ // hide the selectable lists
130
+ jQuery('#interactive_list_items').hide();
131
+ // show our selectable campaigns
132
+ jQuery('#interactive_campaigns').show();
133
+ }
134
+
135
+ // remove active-parent-button class from all elements
136
+ jQuery('.statistics-sub-title').each(function() {
137
+ jQuery(this).removeClass('active-parent-button');
138
+ });
139
+ // re-add it to the clicked element
140
+ jQuery(this).addClass('active-parent-button');
141
+
142
+ // get and store the active parent button,
143
+ // which dictates if we query Growth History Stats
144
+ // or Campaign Stats
145
+ var active_list_button = jQuery('.list_container_for_stats').find('.active_button').text();
146
+ // AJAX request to get campaign data
147
+ jQuery('.mailChimpStatisticsDiv').html('<img class="mailChimp_get_subscribers_preloader" src="<?php echo admin_url().'/images/wpspin_light.gif'; ?>" alt="preloader" >');
148
+ jQuery.ajax({
149
+ type: 'POST',
150
+ url: ajaxurl,
151
+ data: {
152
+ action: 'yks_mailchimp_form',
153
+ form_action: 'yks_get_campaign_data',
154
+ api_key: apiKey,
155
+ // campaign_id: jQuery(this).attr('alt')
156
+ },
157
+ dataType: 'html',
158
+ success: function(response) {
159
+ // reload the chart
160
+ jQuery('.mailChimpStatisticsDiv').html('<div>'+response+'</div>');
161
+ }
162
+ });
163
+
164
+ });
165
+
166
+ // Growth History Click
167
+ jQuery('.growth-history-button').off().on( 'click' , function() {
168
+ var apiKey = '<?php echo $this->optionVal['api-key']; ?>';
169
+ // show and hide the correct div's
170
+ if ( jQuery('#interactive_campaigns').is(':visible') ) {
171
+ // hide the selectable lists
172
+ jQuery('#interactive_campaigns').hide();
173
+ // show our selectable campaigns
174
+ jQuery('#interactive_list_items').show();
175
+ }
176
+
177
+ // remove active-parent-button class from all elements
178
+ jQuery('.statistics-sub-title').each(function() {
179
+ jQuery(this).removeClass('active-parent-button');
180
+ });
181
+ // re-add it to the clicked element
182
+ jQuery(this).addClass('active-parent-button');
183
+
184
+ // get and store the active parent button,
185
+ // which dictates if we query Growth History Stats
186
+ // or Campaign Stats
187
+ var active_parent_button = jQuery('.active-parent-button').text();
188
+
189
+ /** Begin Conditional AJAX **/
190
+ // check the active button is Growth History
191
+ // if so, query Ajax for Growth History Data
192
+ if ( active_parent_button == 'Growth History' ) {
193
+ // smooth scroll back to chart
194
+ jQuery('html, body').animate({
195
+ scrollTop: jQuery(".account-nav-tab").offset().top
196
+ }, 350);
197
+
198
+ // append our preloader , while we fetch the data from MailChimp
199
+ jQuery('.mailChimpStatisticsDiv').html('<img class="mailChimp_get_subscribers_preloader" src="<?php echo admin_url().'/images/wpspin_light.gif'; ?>" alt="preloader" >');
200
+ jQuery.ajax({
201
+ type: 'POST',
202
+ url: ajaxurl,
203
+ data: {
204
+ action: 'yks_mailchimp_form',
205
+ form_action: 'yks_get_growth_data',
206
+ api_key: apiKey,
207
+ list_id: jQuery('.list_container_for_stats').find('.active_button').attr('alt')
208
+ },
209
+ dataType: 'html',
210
+ success: function(response) {
211
+ // reload the chart
212
+ jQuery('.mailChimpStatisticsDiv').html('<div>'+response+'</div>');
213
+ }
214
+ });
215
+ // if the active parent button is Campaign Stats,
216
+ // we should query for Campaign Stats for the specified List
217
+ } else if ( active_parent_button == 'Campaign Stats' ) {
218
+ var apiKey = '<?php echo $this->optionVal['api-key']; ?>';
219
+ jQuery('.mailChimpStatisticsDiv').html('<img class="mailChimp_get_subscribers_preloader" src="<?php echo admin_url().'/images/wpspin_light.gif'; ?>" alt="preloader" >');
220
+ jQuery.ajax({
221
+ type: 'POST',
222
+ url: ajaxurl,
223
+ data: {
224
+ action: 'yks_mailchimp_form',
225
+ form_action: 'yks_get_campaign_data',
226
+ api_key: apiKey,
227
+ // campaign_id: jQuery(this).attr('alt')
228
+ },
229
+ dataType: 'html',
230
+ success: function(response) {
231
+ // reload the chart
232
+ jQuery('.mailChimpStatisticsDiv').html('<div>'+response+'</div>');
233
+ }
234
+ });
235
+ }
236
+
237
+ });
238
+
239
+
240
+ // Ajax to load in our report data for a specific campaign
241
+ // post the data to our get growth list data
242
+ jQuery('.mailChimpStatisticsDiv').off().on().delegate( '.yks-mc-view-report-button', 'click' , function() {
243
+
244
+ // #mailChimpStatisticsDiv
245
+ var campaign_id = jQuery(this).attr('alt');
246
+ var campaign_title = jQuery(this).attr('title');
247
+ var campaign_subject = jQuery(this).parents('.single_report_row').find('.yks-mc-campaign-email-subject').val();
248
+ var campaign_send_date = jQuery(this).parents('.single_report_row').find('.yks-mc-campaign-send-date').val();
249
+ var campaign_send_time = jQuery(this).parents('.single_report_row').find('.yks-mc-campaign-send-time').val();
250
+ var campaign_view_email_link = jQuery(this).parents('.single_report_row').find('.yks-mc-campaign-view-email-link').val();
251
+ var campaign_web_id = jQuery(this).parents('.single_report_row').find('.yks-mc-campaign-web-id').val();
252
+ var apiKey = '<?php echo $this->optionVal['api-key']; ?>';
253
+
254
+ // hide the parent buttons
255
+ jQuery('.statistics-sub-title').hide();
256
+
257
+ // ajax request to get our specific campaign report data
258
+ jQuery('.mailChimpStatisticsDiv').html('<img class="mailChimp_get_subscribers_preloader" style="padding-top:4em;" src="<?php echo admin_url().'/images/wpspin_light.gif'; ?>" alt="preloader" >');
259
+ jQuery.ajax({
260
+ type: 'POST',
261
+ url: ajaxurl,
262
+ data: {
263
+ action: 'yks_mailchimp_form',
264
+ form_action: 'yks_get_specific_campaign_data',
265
+ api_key: apiKey,
266
+ campaign_id: campaign_id,
267
+ campaign_title: campaign_title,
268
+ campaign_subject: campaign_subject ,
269
+ campaign_send_date: campaign_send_date,
270
+ campaign_send_time: campaign_send_time,
271
+ campaign_view_email_link: campaign_view_email_link,
272
+ campaign_web_Id: campaign_web_id
273
+ },
274
+ dataType: 'html',
275
+ success: function(response) {
276
+ jQuery('.mailChimpStatisticsDiv').html('<div>'+response+'</div>');
277
+ }
278
+ });
279
+
280
+ // append our preloader , while we fetch the data from MailChimp
281
+ jQuery.ajax({
282
+ type: 'POST',
283
+ url: ajaxurl,
284
+ data: {
285
+ action: 'yks_mailchimp_form',
286
+ form_action: 'yks_get_specific_campaign_link_data',
287
+ api_key: apiKey,
288
+ campaign_id: campaign_id
289
+ },
290
+ dataType: 'html',
291
+ success: function(response) {
292
+ // reload the chart
293
+ jQuery('#click_tracking_info').html('<div>'+response+'</div>');
294
+ },
295
+ error: function(response) {
296
+ console.log('Error Returned From MailChimp : '+response);
297
+ }
298
+ });
299
+
300
+ // ajax request to get the geo data for opened links
301
+ jQuery.ajax({
302
+ type: 'POST',
303
+ url: ajaxurl,
304
+ data: {
305
+ action: 'yks_mailchimp_form',
306
+ form_action: 'yks_get_campaign_links_geo_opens',
307
+ api_key: apiKey,
308
+ campaign_id: campaign_id
309
+ },
310
+ dataType: 'html',
311
+ success: function(response) {
312
+ jQuery('#geo_data_link_map').html('<div>'+response+'</div>');
313
+ }
314
+ });
315
+
316
+ });
317
+
318
+ var chart_title = jQuery('.active_button').val();
319
+
320
+ if ( chart_title == '' || chart_title == 'All Lists' ) {
321
+ chart_title = 'Account'
322
+ } else {
323
+ chart_title = chart_title+' List';
324
+ }
325
+
326
+ // to do - set up other buttons to load different charts
327
+
328
+ var chart_description = jQuery('.active_chart_button').text();
329
+
330
+ <?php if ( !empty($month_array) ) { ?>
331
+
332
+ // Set up the chart
333
+
334
+ var chart = new Highcharts.Chart({
335
+ chart: {
336
+ renderTo: 'overall_account_growth',
337
+ type: 'column',
338
+ margin: 75,
339
+ options3d: {
340
+ enabled: true,
341
+ alpha: 0,
342
+ beta: 0,
343
+ depth: 50,
344
+ viewDistance: 25
345
+ }
346
+ },
347
+ xAxis: {
348
+ // categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
349
+ categories: [<?php echo '"' . implode( ' ", "' , $month_array ) .'"'; ?>]
350
+ },
351
+ title: {
352
+ text: chart_title+' Growth'
353
+ },
354
+ subtitle: {
355
+ text: 'subscribers gained by month.'
356
+ },
357
+ plotOptions: {
358
+ column: {
359
+ depth: 25
360
+ }
361
+ },
362
+ yAxis: {
363
+ title: {
364
+ text: 'Subscribers'
365
+ }
366
+ },
367
+ series: [{
368
+ // data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]
369
+ data: [<?php echo implode( ', ' , $total_subscriber_array ); ?>],
370
+ showInLegend: true,
371
+ name: "<b><?php _e( 'Total Subscribers' , 'yikes-inc-easy-mailchimp-extender' ); ?></b>",
372
+ },
373
+ {
374
+ data: [<?php echo implode( ', ' , $new_subscriber_array ); ?>],
375
+ showInLegend: true,
376
+ name: "<b><?php _e( 'Imported Subscribers' , 'yikes-inc-easy-mailchimp-extender' ); ?></b>",
377
+ },
378
+ {
379
+ data: [<?php echo implode( ', ' , $optin_subscriber_array ); ?>],
380
+ showInLegend: true,
381
+ name: "<b><?php _e( 'Opt-in Subscribers' , 'yikes-inc-easy-mailchimp-extender' ); ?></b>",
382
+ }
383
+ ],
384
+ credits: {
385
+ enabled: false
386
+ },
387
+ });
388
+
389
+ <?php } else { ?>
390
+ jQuery('.mailChimpStatisticsDiv').html("<div class=no_data_found><?php _e( 'There is no growth data for' , 'yikes-inc-easy-mailchimp-extender' ); ?>"+chart_title+"<?php _e( ' yet' , 'yikes-inc-easy-mailchimp-extender' ); ?></div>");
391
+ <?php } ?>
392
+
393
+ });
394
+ </script>
395
+ <?php } else { ?>
396
+
397
+ <h2 class="no_data_found" style="width:100%;text-align:center;"><?php _e( "No growth data found yet. Please try again at a later time." , "yikes-inc-easy-mailchimp-extender" ); ?></h2>
398
+ <?php } ?>
399
  <div id="overall_account_growth"></div>
templates/mailChimp-profile-template.php CHANGED
@@ -1,20 +1,20 @@
1
- <?php
2
-
3
- // print_r($profile_response);
4
-
5
- ?>
6
-
7
-
8
- <div class="profile_section">
9
-
10
- <h2><?php _e('MailChimp Account Overview', 'yikes-inc-easy-mailchimp-extender'); ?></h2>
11
-
12
- <div class="profile_information" style="margin: 1.5em 0;">
13
- <img src="<?php echo $profile_response['avatar']; ?>" height=125 width=125 style="border-radius:5px;float:left;margin:0 2em 0 2.5em;">
14
- <span class="profile_info_span"><h3><?php _e('Username', 'yikes-inc-easy-mailchimp-extender'); ?> : </h3><?php echo ucfirst($profile_response['username']); ?></span>
15
- <span class="profile_info_span"><h3><?php _e('Name', 'yikes-inc-easy-mailchimp-extender'); ?> : </h3> <?php echo ucfirst($profile_response['name']); ?></span>
16
- <span class="profile_info_span"><h3><?php _e('Email', 'yikes-inc-easy-mailchimp-extender'); ?> : </h3> <?php echo ucfirst($profile_response['email']); ?></span>
17
- <span class="profile_info_span"><h3><?php _e('Account Role', 'yikes-inc-easy-mailchimp-extender'); ?> : </h3> <?php echo ucfirst($profile_response['role']); ?></span>
18
- </div>
19
-
20
- </div>
1
+ <?php
2
+
3
+ // print_r($profile_response);
4
+
5
+ ?>
6
+
7
+
8
+ <div class="profile_section">
9
+
10
+ <h2><?php _e('MailChimp Account Overview', 'yikes-inc-easy-mailchimp-extender'); ?></h2>
11
+
12
+ <div class="profile_information" style="margin: 1.5em 0;">
13
+ <img src="<?php echo $profile_response['avatar']; ?>" height=125 width=125 style="border-radius:5px;float:left;margin:0 2em 0 2.5em;">
14
+ <span class="profile_info_span"><h3><?php _e('Username', 'yikes-inc-easy-mailchimp-extender'); ?> : </h3><?php echo ucfirst($profile_response['username']); ?></span>
15
+ <span class="profile_info_span"><h3><?php _e('Name', 'yikes-inc-easy-mailchimp-extender'); ?> : </h3> <?php echo ucfirst($profile_response['name']); ?></span>
16
+ <span class="profile_info_span"><h3><?php _e('Email', 'yikes-inc-easy-mailchimp-extender'); ?> : </h3> <?php echo ucfirst($profile_response['email']); ?></span>
17
+ <span class="profile_info_span"><h3><?php _e('Account Role', 'yikes-inc-easy-mailchimp-extender'); ?> : </h3> <?php echo ucfirst($profile_response['role']); ?></span>
18
+ </div>
19
+
20
+ </div>
templates/mailChimpChatter-template.php CHANGED
@@ -1,80 +1,87 @@
1
- <?php
2
- // template for displaying the MailChimp
3
- // Chatter on the my MailChimp page
4
-
5
- // loop over the response, to display
6
- // appripriate messages back to the user
7
- // style as best we can, similar to MailChimp
8
- ?>
9
- <div class="yks_mailChimp_Chatter">
10
- <table id="yks-admin-chimp-chatter">
11
- <tbody>
12
- <?php
13
- if ( !empty ( $resp ) ) {
14
- foreach ( $resp as $chatter ) {
15
- echo '<tr class="chatter-table-row">';
16
- // set up the date and time variables
17
- $update_time_explode = explode( ' ', $chatter['update_time'] );
18
- $date = $update_time_explode[0];
19
- $time = $update_time_explode[1];
20
-
21
- // get the type of action that was recorded
22
- $type = explode( ':' , $chatter['type']);
23
-
24
- // set up the image based on the chatter type
25
- // Known Possibilities Include -
26
- // lists:new-subscriber, lists:unsubscribes, lists:profile-updates, campaigns:facebook-likes,
27
- // campaigns:facebook-comments, campaigns:forward-to-friend, lists:imports, or campaigns:inbox-inspections
28
- if ( $type[1] == 'new-subscriber' ) {
29
- $type_image = '<img src="' . plugins_url().'/yikes-inc-easy-mailchimp-extender/images/ChimpChatter/subscriber-added.png' . '" alt="New User Subscribed" class="chimp-chatter-image" />';
30
- } else if ( $type[1] == 'unsubscribes' ) {
31
- $type_image = '<img src="' . plugins_url().'/yikes-inc-easy-mailchimp-extender/images/ChimpChatter/subscriber-removed.png' . '" alt="User Unsubscribed" class="chimp-chatter-image" />';
32
- } else if ( $type[1] == 'profile-updates' ) {
33
- $type_image = '<img src="' . plugins_url().'/yikes-inc-easy-mailchimp-extender/images/ChimpChatter/profile-updated.png' . '" alt="Profile Updated" class="chimp-chatter-image" />';
34
- } else if ( $type[1] == 'facebook-likes' ) {
35
- $type_image = '<img src="' . plugins_url().'/yikes-inc-easy-mailchimp-extender/images/ChimpChatter/facebook-like.png' . '" alt="Facebook Like" class="chimp-chatter-image" />';
36
- } else if ( $type[1] == 'facebook-comments' ) {
37
- $type_image = '<img src="' . plugins_url().'/yikes-inc-easy-mailchimp-extender/images/ChimpChatter/facebook-comment.png' . '" alt="Facebook Comment" class="chimp-chatter-image" />';
38
- } else if ( $type[1] == 'forward-to-friend' ) {
39
- $type_image = '<img src="' . plugins_url().'/yikes-inc-easy-mailchimp-extender/images/ChimpChatter/forward-to-friend.png' . '" alt="Forward To Friend" class="chimp-chatter-image" />';
40
- } else if ( $type[1] == 'imports' ) {
41
- $type_image = '<img src="' . plugins_url().'/yikes-inc-easy-mailchimp-extender/images/ChimpChatter/import.png' . '" alt="Imports" class="chimp-chatter-image" />';
42
- } else if ( $type[1] == 'inbox-inspections' ) {
43
- $type_image = '<img src="' . plugins_url().'/yikes-inc-easy-mailchimp-extender/images/ChimpChatter/inbox-inspection.png' . '" alt="Inbox Inspection" class="chimp-chatter-image" />';
44
- }
45
-
46
- // get and store the returned message
47
- // split the message at ' - ' , which will
48
- // separate the title and messages into two strings
49
- $message = explode( ' - ' , $chatter['message'] );
50
- $message_title = $message[0];
51
- $message_content = $message[1];
52
- // date user subscribed
53
- echo '<td><b>'.date("M d", strtotime($date)).'</b></td>';
54
- // time user subscribed
55
- echo '<td><em>'.date( 'g:i a', strtotime($time) ).'</em></td>';
56
- // visual representation of user action
57
- echo '<td>'.$type_image . '</td>';
58
- // message title of action taken
59
- echo '<td class="chimp-chatter-message"><strong class="chimp-chatter-message-title">'.$message_title.'</strong>';
60
- // message content of action taken
61
- echo '<p>'.$message_content.'</p></td>';
62
- echo '</tr>';
63
-
64
- // empty row for some spacing
65
- echo '<tr class="chatter-table-row"><td>&nbsp;</td></tr>';
66
-
67
- }
68
- } else {
69
- ?>
70
- <tr>
71
- <td style="width:100%;text-align:center !important;">
72
- <h2 class="no_data_found"><?php _e( "No recent account activity. Check back again later." , "yikes-inc-easy-mailchimp-extender" ); ?></h2>
73
- </td>
74
- </tr>
75
- <?php
76
- }
77
- ?>
78
- </tbody>
79
- </table>
 
 
 
 
 
 
 
80
  </div>
1
+ <?php
2
+ // template for displaying the MailChimp
3
+ // Chatter on the my MailChimp page
4
+
5
+ // loop over the response, to display
6
+ // appripriate messages back to the user
7
+ // style as best we can, similar to MailChimp
8
+
9
+ // to do - adjust returned time, to properly format for the timezone
10
+ ?>
11
+ <div class="yks_mailChimp_Chatter">
12
+ <table id="yks-admin-chimp-chatter">
13
+ <tbody>
14
+ <?php
15
+ if ( !empty ( $resp ) ) {
16
+ foreach ( $resp as $chatter ) {
17
+
18
+ $timezone_offset = get_option('gmt_offset');
19
+
20
+ echo '<tr class="chatter-table-row chatter-content-row">';
21
+ // set up the date and time variables
22
+ $update_time_explode = explode( ' ', $chatter['update_time'] );
23
+ $date = $update_time_explode[0];
24
+ $time = $update_time_explode[1];
25
+ $time_explode = explode( ":" , $time );
26
+ $time = ( $time_explode[0] + $timezone_offset ).":".$time_explode[1];
27
+
28
+ // get the type of action that was recorded
29
+ $type = explode( ':' , $chatter['type']);
30
+
31
+ // set up the image based on the chatter type
32
+ // Known Possibilities Include -
33
+ // lists:new-subscriber, lists:unsubscribes, lists:profile-updates, campaigns:facebook-likes,
34
+ // campaigns:facebook-comments, campaigns:forward-to-friend, lists:imports, or campaigns:inbox-inspections
35
+ if ( $type[1] == 'new-subscriber' ) {
36
+ $type_image = '<img src="' . plugins_url().'/yikes-inc-easy-mailchimp-extender/images/ChimpChatter/subscriber-added.png' . '" alt="New User Subscribed" class="chimp-chatter-image" />';
37
+ } else if ( $type[1] == 'unsubscribes' ) {
38
+ $type_image = '<img src="' . plugins_url().'/yikes-inc-easy-mailchimp-extender/images/ChimpChatter/subscriber-removed.png' . '" alt="User Unsubscribed" class="chimp-chatter-image" />';
39
+ } else if ( $type[1] == 'profile-updates' ) {
40
+ $type_image = '<img src="' . plugins_url().'/yikes-inc-easy-mailchimp-extender/images/ChimpChatter/profile-updated.png' . '" alt="Profile Updated" class="chimp-chatter-image" />';
41
+ } else if ( $type[1] == 'facebook-likes' ) {
42
+ $type_image = '<img src="' . plugins_url().'/yikes-inc-easy-mailchimp-extender/images/ChimpChatter/facebook-like.png' . '" alt="Facebook Like" class="chimp-chatter-image" />';
43
+ } else if ( $type[1] == 'facebook-comments' ) {
44
+ $type_image = '<img src="' . plugins_url().'/yikes-inc-easy-mailchimp-extender/images/ChimpChatter/facebook-comment.png' . '" alt="Facebook Comment" class="chimp-chatter-image" />';
45
+ } else if ( $type[1] == 'forward-to-friend' ) {
46
+ $type_image = '<img src="' . plugins_url().'/yikes-inc-easy-mailchimp-extender/images/ChimpChatter/forward-to-friend.png' . '" alt="Forward To Friend" class="chimp-chatter-image" />';
47
+ } else if ( $type[1] == 'imports' ) {
48
+ $type_image = '<img src="' . plugins_url().'/yikes-inc-easy-mailchimp-extender/images/ChimpChatter/import.png' . '" alt="Imports" class="chimp-chatter-image" />';
49
+ } else if ( $type[1] == 'inbox-inspections' ) {
50
+ $type_image = '<img src="' . plugins_url().'/yikes-inc-easy-mailchimp-extender/images/ChimpChatter/inbox-inspection.png' . '" alt="Inbox Inspection" class="chimp-chatter-image" />';
51
+ }
52
+
53
+ // get and store the returned message
54
+ // split the message at ' - ' , which will
55
+ // separate the title and messages into two strings
56
+ $message = explode( ' - ' , $chatter['message'] );
57
+ $message_title = $message[0];
58
+ $message_content = $message[1];
59
+ // date user subscribed
60
+ echo '<td><b>'.date("M d", strtotime($date)).'</b></td>';
61
+ // time user subscribed
62
+ echo '<td><em>'.date( 'g:i a', strtotime($time) ).'</em></td>';
63
+ // visual representation of user action
64
+ echo '<td>'.$type_image . '</td>';
65
+ // message title of action taken
66
+ echo '<td class="chimp-chatter-message"><strong class="chimp-chatter-message-title">'.$message_title.'</strong>';
67
+ // message content of action taken
68
+ echo '<p>'.$message_content.'</p></td>';
69
+ echo '</tr>';
70
+
71
+ // empty row for some spacing
72
+ echo '<tr class="chatter-table-row chatter-spacer-row"><td>&nbsp;</td></tr>';
73
+
74
+ }
75
+ } else {
76
+ ?>
77
+ <tr>
78
+ <td style="width:100%;text-align:center !important;">
79
+ <h2 class="no_data_found"><?php _e( "No recent account activity. Check back again later." , "yikes-inc-easy-mailchimp-extender" ); ?></h2>
80
+ </td>
81
+ </tr>
82
+ <?php
83
+ }
84
+ ?>
85
+ </tbody>
86
+ </table>
87
  </div>
templates/mailChimpChatter-widget-template.php ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // template for displaying the MailChimp
3
+ // Chatter Widget on the Dashboard
4
+
5
+ // loop over the response, to display
6
+ // appripriate messages back to the user
7
+ // style as best we can, similar to MailChimp
8
+ ?>
9
+
10
+ <!-- widget specific styles -->
11
+ <style>
12
+ #yks_mc_account_activity_widget .inside {
13
+ padding: 0;
14
+ margin: 0;
15
+ }
16
+
17
+ #yks-admin-chimp-chatter , .chatter-content-row {
18
+ width: 100%;
19
+ display: table;
20
+ padding: .5em 0;
21
+ }
22
+ .chimp-chatter-image {
23
+ margin-left: 10px !important;
24
+ }
25
+
26
+ .chatter-content-row td:nth-child(2), .chatter-content-row td:nth-child(1) {
27
+ width: 65px !important;
28
+ text-align: center;
29
+ }
30
+
31
+ #yks_mc_account_activity_widget > h3 > span:before {
32
+ content: url('<?php echo plugins_url(); ?>/yikes-inc-easy-mailchimp-extender/images/yikes_logo_widget_icon.png');
33
+ width:33px;
34
+ float:left;
35
+ height:10px;
36
+ margin: -3px 10px 0 0px;
37
+ }
38
+ </style>
39
+
40
+
41
+ <div class="yks_mailChimp_Chatter">
42
+ <table id="yks-admin-chimp-chatter">
43
+ <tbody>
44
+ <?php
45
+ if ( !empty ( $resp ) ) {
46
+ $i = 1;
47
+
48
+ foreach ( $resp as $chatter ) {
49
+
50
+ // specify the number of items you want
51
+ // returned to the widget here
52
+ if ( $i > 8 ) {
53
+ break;
54
+ } else {
55
+
56
+ // get our timezone offset so we
57
+ // can return the proper time to the user
58
+ $timezone_offset = get_option('gmt_offset');
59
+
60
+ // decide if the row should be even or odd
61
+ // used for zebra striping the table
62
+ if ( $i % 2 == 0 ) {
63
+ echo '<tr class="chatter-table-row chatter-content-row alternate">';
64
+ } else {
65
+ echo '<tr class="chatter-table-row chatter-content-row">';
66
+ }
67
+ // set up the date and time variables
68
+ $update_time_explode = explode( ' ', $chatter['update_time'] );
69
+ $date = $update_time_explode[0];
70
+ $time = $update_time_explode[1];
71
+ $time_explode = explode( ":" , $time );
72
+ $time = ( $time_explode[0] + $timezone_offset ).":".$time_explode[1];
73
+
74
+ // get the type of action that was recorded
75
+ $type = explode( ':' , $chatter['type']);
76
+
77
+ // set up the image based on the chatter type
78
+ // Known Possibilities Include -
79
+ // lists:new-subscriber, lists:unsubscribes, lists:profile-updates, campaigns:facebook-likes,
80
+ // campaigns:facebook-comments, campaigns:forward-to-friend, lists:imports, or campaigns:inbox-inspections
81
+ if ( $type[1] == 'new-subscriber' ) {
82
+ $type_image = '<img src="' . plugins_url().'/yikes-inc-easy-mailchimp-extender/images/ChimpChatter/subscriber-added.png' . '" alt="New User Subscribed" class="chimp-chatter-image" />';
83
+ } else if ( $type[1] == 'unsubscribes' ) {
84
+ $type_image = '<img src="' . plugins_url().'/yikes-inc-easy-mailchimp-extender/images/ChimpChatter/subscriber-removed.png' . '" alt="User Unsubscribed" class="chimp-chatter-image" />';
85
+ } else if ( $type[1] == 'profile-updates' ) {
86
+ $type_image = '<img src="' . plugins_url().'/yikes-inc-easy-mailchimp-extender/images/ChimpChatter/profile-updated.png' . '" alt="Profile Updated" class="chimp-chatter-image" />';
87
+ } else if ( $type[1] == 'facebook-likes' ) {
88
+ $type_image = '<img src="' . plugins_url().'/yikes-inc-easy-mailchimp-extender/images/ChimpChatter/facebook-like.png' . '" alt="Facebook Like" class="chimp-chatter-image" />';
89
+ } else if ( $type[1] == 'facebook-comments' ) {
90
+ $type_image = '<img src="' . plugins_url().'/yikes-inc-easy-mailchimp-extender/images/ChimpChatter/facebook-comment.png' . '" alt="Facebook Comment" class="chimp-chatter-image" />';
91
+ } else if ( $type[1] == 'forward-to-friend' ) {
92
+ $type_image = '<img src="' . plugins_url().'/yikes-inc-easy-mailchimp-extender/images/ChimpChatter/forward-to-friend.png' . '" alt="Forward To Friend" class="chimp-chatter-image" />';
93
+ } else if ( $type[1] == 'imports' ) {
94
+ $type_image = '<img src="' . plugins_url().'/yikes-inc-easy-mailchimp-extender/images/ChimpChatter/import.png' . '" alt="Imports" class="chimp-chatter-image" />';
95
+ } else if ( $type[1] == 'inbox-inspections' ) {
96
+ $type_image = '<img src="' . plugins_url().'/yikes-inc-easy-mailchimp-extender/images/ChimpChatter/inbox-inspection.png' . '" alt="Inbox Inspection" class="chimp-chatter-image" />';
97
+ }
98
+
99
+ // get and store the returned message
100
+ // split the message at ' - ' , which will
101
+ // separate the title and messages into two strings
102
+ $message = explode( ' - ' , $chatter['message'] );
103
+ $message_title = $message[0];
104
+ $message_content = $message[1];
105
+ // visual representation of user action
106
+ echo '<td>'.$type_image . '</td>';
107
+ // date user subscribed
108
+ echo '<td><b>'.date("M d", strtotime($date)).'</b><br /><em>'.date( 'g:i a', strtotime($time) ).'</em></td>';
109
+ // message title of action taken
110
+ echo '<td class="chimp-chatter-message"><strong class="chimp-chatter-message-title">'.$message_title.'</strong>';
111
+ echo '</tr>';
112
+
113
+ }
114
+ $i++;
115
+ }
116
+ } else {
117
+ ?>
118
+ <tr>
119
+ <td style="width:100%;text-align:center !important;">
120
+ <h2 class="no_data_found" style="font-size:1.25em;font-style:italic;"><?php _e( "No recent account activity. Check back again later." , "yikes-inc-easy-mailchimp-extender" ); ?></h2>
121
+ </td>
122
+ </tr>
123
+ <?php
124
+ }
125
+ ?>
126
+ </tbody>
127
+ </table>
128
+ </div>
templates/shortcode_error_exists.php CHANGED
@@ -1,3 +1,3 @@
1
- <p>
2
- <?php _e( 'This list was already placed on this page!' , 'yikes-inc-easy-mailchimp-extender' ); ?>
3
  </p>
1
+ <p>
2
+ <?php _e( 'This list was already placed on this page!' , 'yikes-inc-easy-mailchimp-extender' ); ?>
3
  </p>
templates/shortcode_error_no_API_key.php CHANGED
@@ -1,3 +1,3 @@
1
- <p>
2
- <?php _e( 'Woops! No Valid API Key Found. Double check your settings.' , 'yikes-inc-easy-mailchimp-extender' ); ?>
3
  </p>
1
+ <p>
2
+ <?php _e( 'Woops! No Valid API Key Found. Double check your settings.' , 'yikes-inc-easy-mailchimp-extender' ); ?>
3
  </p>
templates/shortcode_form.php CHANGED
@@ -56,7 +56,7 @@ $ymce = jQuery.noConflict();
56
  dataType: 'text',
57
  success: function(MAILCHIMP)
58
  {
59
- if(MAILCHIMP == '1')
60
  {
61
  // custom message based on opt-in settings value
62
  // single opt-in
56
  dataType: 'text',
57
  success: function(MAILCHIMP)
58
  {
59
+ if( MAILCHIMP.trim() == 1 )
60
  {
61
  // custom message based on opt-in settings value
62
  // single opt-in
yikes-inc-easy-mailchimp-extender.php CHANGED
@@ -4,7 +4,7 @@
4
  Plugin Name: Easy MailChimp Forms
5
  Plugin URI: http://www.yikesinc.com/services/yikes-inc-easy-mailchimp-extender/
6
  Description: Mailchimp integration in the form of a shortcode, php snippet or widget. Now track account status, campaign stats, view subscribers and so much more!
7
- Version: 5.0.3
8
  Author: YIKES Inc
9
  Author URI: http://yikesinc.com
10
  License: GPL2
@@ -30,7 +30,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
30
 
31
  /** Configuration **/
32
  if(!defined('YKSEME_DEBUG')) define('YKSEME_DEBUG', false);
33
- if(!defined('YKSEME_VERSION_CURRENT')) define('YKSEME_VERSION_CURRENT', '5.0.3');
34
  if(!defined('YKSEME_REQ_PHP')) define('YKSEME_REQ_PHP', '5.0');
35
  if(!defined('YKSEME_AUTHOR')) define('YKSEME_AUTHOR', 'YIKES Inc');
36
  if(!defined('YKSEME_SITE')) define('YKSEME_SITE', site_url().'/');
@@ -43,22 +43,21 @@ if(!defined('YKSEME_URL_WP_ADM')) define('YKSEME_URL_WP_ADM', YKSEME_URL_W
43
  if(!defined('YKSEME_OPTION')) define('YKSEME_OPTION', YKSEME_PREFIX.'storage');
44
  // Conditional check for SSL enabled site
45
  if(!defined('YKSEME_URL_WP_AJAX')) {
46
- if ($_SERVER['SERVER_PORT'] == 80)
47
- define('YKSEME_URL_WP_AJAX', admin_url('admin-ajax.php', 'http'));
48
- else if ($_SERVER['SERVER_PORT'] == 443)
49
- define('YKSEME_URL_WP_AJAX', admin_url('admin-ajax.php', 'https'));
50
- else
51
- define('YKSEME_URL_WP_AJAX', admin_url('admin-ajax.php'));
52
  }
53
  if(!defined('YKSEME_URL_CURRENT')) define('YKSEME_URL_CURRENT', $_SERVER['REQUEST_URI']);
54
 
55
 
56
  /** Localization **/
57
  // include translated files
58
- function myplugin_init() {
59
- load_plugin_textdomain('yikes-inc-easy-mailchimp-extender', false, dirname(plugin_basename(__FILE__)) . '/languages');
60
  }
61
- add_action('init', 'myplugin_init');
62
 
63
  /** Initial Configuration **/
64
  if(YKSEME_DEBUG) error_reporting(E_ALL ^ E_NOTICE);
4
  Plugin Name: Easy MailChimp Forms
5
  Plugin URI: http://www.yikesinc.com/services/yikes-inc-easy-mailchimp-extender/
6
  Description: Mailchimp integration in the form of a shortcode, php snippet or widget. Now track account status, campaign stats, view subscribers and so much more!
7
+ Version: 5.0.4
8
  Author: YIKES Inc
9
  Author URI: http://yikesinc.com
10
  License: GPL2
30
 
31
  /** Configuration **/
32
  if(!defined('YKSEME_DEBUG')) define('YKSEME_DEBUG', false);
33
+ if(!defined('YKSEME_VERSION_CURRENT')) define('YKSEME_VERSION_CURRENT', '5.0.4');
34
  if(!defined('YKSEME_REQ_PHP')) define('YKSEME_REQ_PHP', '5.0');
35
  if(!defined('YKSEME_AUTHOR')) define('YKSEME_AUTHOR', 'YIKES Inc');
36
  if(!defined('YKSEME_SITE')) define('YKSEME_SITE', site_url().'/');
43
  if(!defined('YKSEME_OPTION')) define('YKSEME_OPTION', YKSEME_PREFIX.'storage');
44
  // Conditional check for SSL enabled site
45
  if(!defined('YKSEME_URL_WP_AJAX')) {
46
+ if ( is_ssl() ) {
47
+ define('YKSEME_URL_WP_AJAX', admin_url('admin-ajax.php', 'https'));
48
+ } else {
49
+ define('YKSEME_URL_WP_AJAX', admin_url('admin-ajax.php', 'http'));
50
+ }
 
51
  }
52
  if(!defined('YKSEME_URL_CURRENT')) define('YKSEME_URL_CURRENT', $_SERVER['REQUEST_URI']);
53
 
54
 
55
  /** Localization **/
56
  // include translated files
57
+ function yks_mc_text_domain_init() {
58
+ load_plugin_textdomain('yikes-inc-easy-mailchimp-extender', false, dirname(plugin_basename(__FILE__)) . '/languages');
59
  }
60
+ add_action('init', 'yks_mc_text_domain_init');
61
 
62
  /** Initial Configuration **/
63
  if(YKSEME_DEBUG) error_reporting(E_ALL ^ E_NOTICE);