Email Subscribers & Newsletters - Version 4.1.2

Version Description

(29.05.2019) = * New: Added support to export "Unconfirmed" contacts.

Download this release

Release Info

Developer Icegram
Plugin Icon 128x128 Email Subscribers & Newsletters
Version 4.1.2
Comparing to
See all releases

Code changes from version 4.1.1 to 4.1.2

admin/class-email-subscribers-admin.php CHANGED
@@ -198,8 +198,8 @@ class Email_Subscribers_Admin {
198
  // Function for Klawoo's Subscribe form on Help & Info page
199
  public static function klawoo_subscribe() {
200
  $url = 'http://app.klawoo.com/subscribe';
201
- if( !empty($_REQUEST['form-source']) ){
202
- update_option('ig_es_onboarding_status', $_REQUEST['form-source']);
203
  }
204
  if ( ! empty( $_POST ) ) {
205
  $params = $_POST;
@@ -289,10 +289,10 @@ class Email_Subscribers_Admin {
289
  public function do_send( $response, $data ) {
290
  global $phpmailer;
291
 
292
- if ( ! is_object( $phpmailer ) || ! is_a( $phpmailer, 'PHPMailer' ) ) {
293
- require_once ABSPATH . WPINC . '/class-phpmailer.php';
294
- $phpmailer = new PHPMailer( true );
295
- }
296
 
297
  $to_email = $data['to_email'];
298
  $subject = $data['subject'];
@@ -300,18 +300,18 @@ class Email_Subscribers_Admin {
300
  $headers = $data['headers'];
301
 
302
  $send_mail = wp_mail( $to_email, $subject, $email_template, $headers );
303
- $result = array('status' => 'SUCCESS');
304
 
305
- if(!$send_mail) {
306
 
307
- $result = array(
308
- 'status' => 'ERROR',
309
- 'message' => wp_strip_all_tags( $phpmailer->ErrorInfo )
310
- );
311
 
312
- }
313
 
314
- return $result;
315
  }
316
 
317
  function submenu_order( $menu_order ) {
@@ -355,23 +355,29 @@ class Email_Subscribers_Admin {
355
  }
356
 
357
  public function es_dashboard_callback() {
358
- $es_plugin_data = get_plugin_data( plugin_dir_path( __DIR__ ) . 'email-subscribers.php' );
359
- $es_current_version = $es_plugin_data['Version'];
360
- $admin_email = get_option( 'admin_email' );
361
- $ig_es_4015_db_updated_at = get_option( 'ig_es_4015_db_updated_at', false);
362
- $onboarding_status = get_option( 'ig_es_onboarding_complete', 'no');
363
- if ( !$ig_es_4015_db_updated_at && 'yes' !== $onboarding_status) {
364
  include plugin_dir_path( dirname( __FILE__ ) ) . 'admin/partials/onboarding.php';
365
- }else{
366
  include plugin_dir_path( dirname( __FILE__ ) ) . 'admin/partials/dashboard.php';
367
  }
368
 
369
  }
370
 
371
  public static function es_feedback() {
372
- // if ( get_option( 'es_star_review' ) != 1 ) {
373
- // echo '<div class="notice notice-warning" style="background-color: #FFF;"><p style="letter-spacing: 0.6px;">If you like <strong>Email Subscribers</strong>, please consider leaving us a <a target="_blank" href="https://wordpress.org/support/plugin/email-subscribers/reviews/?filter=5#new-post"><span>&#9733;</span><span>&#9733;</span><span>&#9733;</span><span>&#9733;</span><span>&#9733;</span></a> rating. A huge thank you from Icegram in advance! <a style="float:right" class="es-admin-btn es-admin-btn-secondary" href="' . admin_url() . 'admin.php?page=es_dashboard&dismiss_admin_notice=1&option_name=es_star_review">No, I don\'t like it</a></p></div>';
374
- // }
 
 
 
 
 
 
375
  }
376
 
377
 
@@ -387,19 +393,19 @@ class Email_Subscribers_Admin {
387
  <?php
388
  }
389
 
390
- function send_test_email(){
391
  $message = array();
392
  $message = array(
393
- 'status' => 'ERROR',
394
- 'message' => __('Something went wrong', 'email-subscribers')
395
- );
396
- if(!empty($_REQUEST['emails'])){
397
- $emails = $_REQUEST['emails'];
398
  $default_list = ES_DB_Lists::get_list_by_name( IG_DEFAULT_LIST );
399
- $list_id = $default_list['id'];
400
  //add to the default list
401
- foreach ($emails as $email) {
402
- $data = array(
403
  'first_name' => ES_Common::get_name_from_email( $email ),
404
  'email' => $email,
405
  'source' => 'admin',
@@ -425,21 +431,21 @@ class Email_Subscribers_Admin {
425
  }
426
  $res = ES_Install::create_and_send_default_broadcast();
427
  $res = ES_Install::create_and_send_default_post_notification();
428
- if( $res['status'] === 'SUCCESS'){
429
- update_option('ig_es_onboarding_test_campaign_success', 'yes');
430
- }else{
431
- update_option('ig_es_onboarding_test_campaign_error', 'yes');
432
  }
433
- update_option('ig_es_onboarding_complete', 'yes');
434
- $res['dashboard_url'] = admin_url('admin.php?page=es_dashboard');
435
- echo json_encode($res);
436
  exit;
437
 
438
  }
439
  }
440
 
441
  //save skip signup option
442
- function es_save_onboarding_skip(){
443
  if ( isset( $_GET['es_skip'] ) && $_GET['es_skip'] == '1' && isset( $_GET['option_name'] ) ) {
444
  $option_name = sanitize_text_field( $_GET['option_name'] );
445
  update_option( 'ig_es_ob_skip_' . $option_name, 'yes' );
198
  // Function for Klawoo's Subscribe form on Help & Info page
199
  public static function klawoo_subscribe() {
200
  $url = 'http://app.klawoo.com/subscribe';
201
+ if ( ! empty( $_REQUEST['form-source'] ) ) {
202
+ update_option( 'ig_es_onboarding_status', $_REQUEST['form-source'] );
203
  }
204
  if ( ! empty( $_POST ) ) {
205
  $params = $_POST;
289
  public function do_send( $response, $data ) {
290
  global $phpmailer;
291
 
292
+ if ( ! is_object( $phpmailer ) || ! is_a( $phpmailer, 'PHPMailer' ) ) {
293
+ require_once ABSPATH . WPINC . '/class-phpmailer.php';
294
+ $phpmailer = new PHPMailer( true );
295
+ }
296
 
297
  $to_email = $data['to_email'];
298
  $subject = $data['subject'];
300
  $headers = $data['headers'];
301
 
302
  $send_mail = wp_mail( $to_email, $subject, $email_template, $headers );
303
+ $result = array( 'status' => 'SUCCESS' );
304
 
305
+ if ( ! $send_mail ) {
306
 
307
+ $result = array(
308
+ 'status' => 'ERROR',
309
+ 'message' => wp_strip_all_tags( $phpmailer->ErrorInfo )
310
+ );
311
 
312
+ }
313
 
314
+ return $result;
315
  }
316
 
317
  function submenu_order( $menu_order ) {
355
  }
356
 
357
  public function es_dashboard_callback() {
358
+ $es_plugin_data = get_plugin_data( plugin_dir_path( __DIR__ ) . 'email-subscribers.php' );
359
+ $es_current_version = $es_plugin_data['Version'];
360
+ $admin_email = get_option( 'admin_email' );
361
+ $ig_es_4015_db_updated_at = get_option( 'ig_es_4015_db_updated_at', false );
362
+ $onboarding_status = get_option( 'ig_es_onboarding_complete', 'no' );
363
+ if ( ! $ig_es_4015_db_updated_at && 'yes' !== $onboarding_status ) {
364
  include plugin_dir_path( dirname( __FILE__ ) ) . 'admin/partials/onboarding.php';
365
+ } else {
366
  include plugin_dir_path( dirname( __FILE__ ) ) . 'admin/partials/dashboard.php';
367
  }
368
 
369
  }
370
 
371
  public static function es_feedback() {
372
+ $star_rating_dismiss = get_option( 'ig_es_dismiss_star_notice', 'no' );
373
+ $star_rating_done = get_option( 'ig_es_star_notice_done', 'no' );
374
+ // Show if - more than 2 post notifications or Newsletters sent OR more than 10 subscribers
375
+ $total_contacts = ES_DB_Contacts::count_active_subscribers_by_list_id();
376
+ $total_email_sent = ES_DB_Mailing_Queue::get_notifications_count();
377
+
378
+ if ( ( $total_contacts >= 10 || $total_email_sent > 2 ) && 'yes' !== $star_rating_dismiss && 'yes' !== $star_rating_done ) {
379
+ echo '<div class="notice notice-warning" style="background-color: #FFF;"><p style="letter-spacing: 0.6px;">If you like <strong>Email Subscribers</strong>, please consider leaving us a <a target="_blank" href="?es_dismiss_admin_notice=1&option_name=star_notice_done"><span>&#9733;</span><span>&#9733;</span><span>&#9733;</span><span>&#9733;</span><span>&#9733;</span></a> rating. A huge thank you from Icegram in advance! <a style="float:right" class="es-admin-btn es-admin-btn-secondary" href="?es_dismiss_admin_notice=1&option_name=dismiss_star_notice">No, I don\'t like it</a></p></div>';
380
+ }
381
  }
382
 
383
 
393
  <?php
394
  }
395
 
396
+ function send_test_email() {
397
  $message = array();
398
  $message = array(
399
+ 'status' => 'ERROR',
400
+ 'message' => __( 'Something went wrong', 'email-subscribers' )
401
+ );
402
+ if ( ! empty( $_REQUEST['emails'] ) ) {
403
+ $emails = $_REQUEST['emails'];
404
  $default_list = ES_DB_Lists::get_list_by_name( IG_DEFAULT_LIST );
405
+ $list_id = $default_list['id'];
406
  //add to the default list
407
+ foreach ( $emails as $email ) {
408
+ $data = array(
409
  'first_name' => ES_Common::get_name_from_email( $email ),
410
  'email' => $email,
411
  'source' => 'admin',
431
  }
432
  $res = ES_Install::create_and_send_default_broadcast();
433
  $res = ES_Install::create_and_send_default_post_notification();
434
+ if ( $res['status'] === 'SUCCESS' ) {
435
+ update_option( 'ig_es_onboarding_test_campaign_success', 'yes' );
436
+ } else {
437
+ update_option( 'ig_es_onboarding_test_campaign_error', 'yes' );
438
  }
439
+ update_option( 'ig_es_onboarding_complete', 'yes' );
440
+ $res['dashboard_url'] = admin_url( 'admin.php?page=es_dashboard' );
441
+ echo json_encode( $res );
442
  exit;
443
 
444
  }
445
  }
446
 
447
  //save skip signup option
448
+ function es_save_onboarding_skip() {
449
  if ( isset( $_GET['es_skip'] ) && $_GET['es_skip'] == '1' && isset( $_GET['option_name'] ) ) {
450
  $option_name = sanitize_text_field( $_GET['option_name'] );
451
  update_option( 'ig_es_ob_skip_' . $option_name, 'yes' );
admin/css/email-subscribers-admin.css CHANGED
@@ -392,6 +392,9 @@ p.search-box.box-ma10 {
392
  }
393
 
394
  /**** Dashboard : start ***/
 
 
 
395
  .wrap.about-wrap {
396
  background-color: transparent;
397
  position: relative;
@@ -798,7 +801,7 @@ h5.es-badge {
798
  }
799
 
800
  .es-facebook.column i.dashicons-facebook {
801
- font-size: 2.5em;
802
  line-height: 0.6em;
803
  color: #28487D;
804
  margin: 0.2em 0;
@@ -1178,3 +1181,24 @@ div.es .one-third {
1178
  div.es .last {
1179
  margin-right: 0;
1180
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
392
  }
393
 
394
  /**** Dashboard : start ***/
395
+ .toplevel_page_es_dashboard .about-header{
396
+ margin-top: 2em;
397
+ }
398
  .wrap.about-wrap {
399
  background-color: transparent;
400
  position: relative;
801
  }
802
 
803
  .es-facebook.column i.dashicons-facebook {
804
+ font-size: 5em;
805
  line-height: 0.6em;
806
  color: #28487D;
807
  margin: 0.2em 0;
1181
  div.es .last {
1182
  margin-right: 0;
1183
  }
1184
+
1185
+ .ig-es-feedback-button {
1186
+ height: 40px;
1187
+ border: solid 3px #CCCCCC;
1188
+ background: #333;
1189
+ width: 100px;
1190
+ line-height: 32px;
1191
+ -webkit-transform: rotate(-90deg);
1192
+ font-weight: 600;
1193
+ color: white;
1194
+ transform: rotate(-90deg);
1195
+ -ms-transform: rotate(-90deg);
1196
+ -moz-transform: rotate(-90deg);
1197
+ text-align: center;
1198
+ font-size: 17px;
1199
+ position: fixed;
1200
+ right: -40px;
1201
+ top: 45%;
1202
+ font-family: "Roboto", helvetica, arial, sans-serif;
1203
+ z-index: 999;
1204
+ }
admin/js/email-subscribers-admin.js CHANGED
@@ -136,6 +136,8 @@
136
  });
137
 
138
  });
 
 
139
  });
140
 
141
 
136
  });
137
 
138
  });
139
+
140
+
141
  });
142
 
143
 
admin/partials/dashboard.php CHANGED
@@ -100,8 +100,8 @@ if ( ! defined( 'ABSPATH' ) ) {
100
  </div>
101
  <div class="es-facebook column">
102
  <p><strong><?php _e('<span>Join our</span> Email Subscribers Secret Club!','email-subscribers'); ?></strong></p>
103
- <p><?php _e('Be a part of development, share your valuable feedback and get early access to our upcoming <strong>Email Subscribers 5.0</strong>', 'email-subscribers'); ?></p>
104
- <p><a style="text-decoration: none" target="_blank" href="https://www.facebook.com/groups/2298909487017349/"><i class="dashicons dashicons-es dashicons-facebook"></i></a></p>
105
  </div>
106
  <div class="es-lower">
107
  <div class="es-version">
100
  </div>
101
  <div class="es-facebook column">
102
  <p><strong><?php _e('<span>Join our</span> Email Subscribers Secret Club!','email-subscribers'); ?></strong></p>
103
+ <p><?php _e('Be a part of growing Email Subscribers community. Share your valuable feedback and get quick help from community. It\'s a great way to connect with real people', 'email-subscribers'); ?></p>
104
+ <p style="text-align: center;" ><a style="text-decoration: none" target="_blank" href="https://www.facebook.com/groups/2298909487017349/"><i class="dashicons dashicons-es dashicons-facebook"></i></a></p>
105
  </div>
106
  <div class="es-lower">
107
  <div class="es-version">
admin/partials/pricing.php CHANGED
@@ -46,7 +46,7 @@ if ( ! defined( 'ABSPATH' ) ) {
46
  </style>
47
  <div class="es-starter-gopro">
48
  <img src="<?php echo EMAIL_SUBSCRIBERS_URL.'/admin/images/pricing.png' ?>"/><br/>
49
- <a class="button large green-light" href="https://www.icegram.com/email-subscribers-pricing/?utm_source=in_app&utm_medium=go_pro_monthly&utm_campaign=starter_launch" target="_blank"> <?php _e('Get Started @ $5/month', 'email-subscribers') ?></a>
50
  <div class="mid-or">OR</div>
51
- <a class="button large green" href="https://www.icegram.com/email-subscribers-pricing/?utm_source=in_app&utm_medium=go_pro_yearly&utm_campaign=starter_launch" target="_blank"> <?php _e('Get Started @ $29/year', 'email-subscribers') ?></a>
52
  </div>
46
  </style>
47
  <div class="es-starter-gopro">
48
  <img src="<?php echo EMAIL_SUBSCRIBERS_URL.'/admin/images/pricing.png' ?>"/><br/>
49
+ <a class="button large green-light" href="https://www.icegram.com/email-subscribers-pricing/?utm_source=in_app&utm_medium=go_pro_monthly&utm_campaign=starter_launch" target="_blank"> <?php _e('Get Started @ $9/month', 'email-subscribers') ?></a>
50
  <div class="mid-or">OR</div>
51
+ <a class="button large green" href="https://www.icegram.com/email-subscribers-pricing/?utm_source=in_app&utm_medium=go_pro_yearly&utm_campaign=starter_launch" target="_blank"> <?php _e('Get Started @ $49/year', 'email-subscribers') ?></a>
52
  </div>
email-subscribers.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: Email Subscribers & Newsletters
4
  * Plugin URI: https://www.icegram.com/
5
  * Description: Add subscription forms on website, send HTML newsletters & automatically notify subscribers about new blog posts once it is published.
6
- * Version: 4.1.1
7
  * Author: Icegram
8
  * Author URI: https://www.icegram.com/
9
  * Requires at least: 3.9
@@ -24,9 +24,8 @@ if ( ! defined( 'WPINC' ) ) {
24
  * Define constants
25
  */
26
  define( 'ES_PLUGIN_DIR', dirname( __FILE__ ) );
27
- define( 'ES_PLUGIN_VERSION', '4.1.1' );
28
  define( 'ES_PLUGIN_BASE_NAME', plugin_basename( __FILE__ ) );
29
- define( 'IG_ES_DEV_MODE', false);
30
 
31
  if ( ! defined( 'ES_PLUGIN_FILE' ) ) {
32
  define( 'ES_PLUGIN_FILE', __FILE__ );
3
  * Plugin Name: Email Subscribers & Newsletters
4
  * Plugin URI: https://www.icegram.com/
5
  * Description: Add subscription forms on website, send HTML newsletters & automatically notify subscribers about new blog posts once it is published.
6
+ * Version: 4.1.2
7
  * Author: Icegram
8
  * Author URI: https://www.icegram.com/
9
  * Requires at least: 3.9
24
  * Define constants
25
  */
26
  define( 'ES_PLUGIN_DIR', dirname( __FILE__ ) );
27
+ define( 'ES_PLUGIN_VERSION', '4.1.2' );
28
  define( 'ES_PLUGIN_BASE_NAME', plugin_basename( __FILE__ ) );
 
29
 
30
  if ( ! defined( 'ES_PLUGIN_FILE' ) ) {
31
  define( 'ES_PLUGIN_FILE', __FILE__ );
includes/admin/class-es-admin-settings.php CHANGED
@@ -29,6 +29,7 @@ class ES_Admin_Settings {
29
 
30
  public function es_settings_callback() {
31
 
 
32
  $submitted = ! empty( $_POST['submitted'] ) ? $_POST['submitted'] : '';
33
  $submit_action = ! empty( $_POST['submit_action'] ) ? $_POST['submit_action'] : '';
34
 
@@ -628,5 +629,4 @@ class ES_Admin_Settings {
628
  }
629
 
630
 
631
-
632
  }
29
 
30
  public function es_settings_callback() {
31
 
32
+
33
  $submitted = ! empty( $_POST['submitted'] ) ? $_POST['submitted'] : '';
34
  $submit_action = ! empty( $_POST['submit_action'] ) ? $_POST['submit_action'] : '';
35
 
629
  }
630
 
631
 
 
632
  }
includes/admin/class-es-export-subscribers.php CHANGED
@@ -55,7 +55,7 @@ class Export_Subscribers {
55
  ?>
56
 
57
  <tr>
58
- <th scope="col"><?php _e( 'No', 'email-subscribers' ); ?></th>
59
  <th scope="col"><?php _e( 'Contacts', 'email-subscribers' ); ?></th>
60
  <th scope="col"><?php _e( 'Total Contacts', 'email-subscribers' ); ?></th>
61
  <th scope="col"><?php _e( 'Export', 'email-subscribers' ); ?></th>
@@ -67,9 +67,11 @@ class Export_Subscribers {
67
  public function prepare_body() {
68
 
69
  $export_lists = array(
70
- 'all' => __( 'All Contacts', 'email-subscribers' ),
71
- 'active' => __( 'Subscribed Contacts', 'email-subscribers' ),
72
- 'inactive' => __( 'Unsubscribed Contacts', 'email-subscribers' )
 
 
73
  );
74
 
75
  $i = 1;
@@ -105,7 +107,7 @@ class Export_Subscribers {
105
  <div class="wrap">
106
  <h2 style="margin-bottom:1em;">
107
  <?php _e( 'Audience > Export Contacts', 'email-subscribers' );
108
- ES_Common::prepare_main_header_navigation($audience_tab_main_navigation);
109
  ?>
110
  </h2>
111
  <div class="tool-box">
@@ -152,6 +154,10 @@ class Export_Subscribers {
152
  $sql = "SELECT COUNT(email) FROM " . IG_CONTACTS_TABLE . " WHERE unsubscribed = 1 ";
153
  break;
154
 
 
 
 
 
155
  case 'registered':
156
  case 'commented':
157
  // Registered/ Commented Subscribers
@@ -200,7 +206,6 @@ class Export_Subscribers {
200
 
201
  }
202
 
203
-
204
  public function generate_csv( $status = 'all' ) {
205
 
206
  global $wpdb;
@@ -209,12 +214,16 @@ class Export_Subscribers {
209
  set_time_limit( IG_SET_TIME_LIMIT );
210
 
211
  $email_subscribe_table = IG_CONTACTS_TABLE;
 
 
212
  if ( 'active' === $status ) {
213
  $query = "SELECT `first_name`, `last_name`, `email`, `status`, `unsubscribed`, `created_at` FROM $email_subscribe_table WHERE unsubscribed = 0 OR unsubscribed IS NULL";
214
  } elseif ( 'inactive' === $status ) {
215
  $query = "SELECT `first_name`, `last_name`, `email`, `status`, `unsubscribed`, `created_at` FROM $email_subscribe_table WHERE unsubscribed = 1 ";
216
- } else {
217
  $query = "SELECT `first_name`, `last_name`, `email`, `status`, `unsubscribed`, `created_at` FROM $email_subscribe_table";
 
 
218
  }
219
 
220
  $subscribers = $wpdb->get_results( $query, ARRAY_A );
@@ -233,15 +242,20 @@ class Export_Subscribers {
233
  $csv_output .= "\n";
234
 
235
  foreach ( $subscribers as $key => $subscriber ) {
236
- $data['name'] = trim( $subscriber['first_name'] . ' ' . $subscriber['last_name'] );
237
- $data['email'] = trim( $subscriber['email'] );
238
- $data['status'] = ( $subscriber['unsubscribed'] == 1 ) ? __( 'Unsubscribed', 'email-subscribers' ) : __( 'Subscribed', 'email-subscribers' );
 
 
 
 
 
 
239
  $data['created_at'] = $subscriber['created_at'];
240
 
241
  $csv_output .= implode( ',', $data );
242
  $csv_output .= "\n";
243
  }
244
-
245
  }
246
 
247
  return $csv_output;
55
  ?>
56
 
57
  <tr>
58
+ <th scope="col"><?php _e( 'No.', 'email-subscribers' ); ?></th>
59
  <th scope="col"><?php _e( 'Contacts', 'email-subscribers' ); ?></th>
60
  <th scope="col"><?php _e( 'Total Contacts', 'email-subscribers' ); ?></th>
61
  <th scope="col"><?php _e( 'Export', 'email-subscribers' ); ?></th>
67
  public function prepare_body() {
68
 
69
  $export_lists = array(
70
+
71
+ 'all' => __( 'All Contacts', 'email-subscribers' ),
72
+ 'active' => __( 'Subscribed Contacts', 'email-subscribers' ),
73
+ 'inactive' => __( 'Unsubscribed Contacts', 'email-subscribers' ),
74
+ 'unconfirmed' => __( 'Unconfirmed Contacts', 'email-subscribers' ),
75
  );
76
 
77
  $i = 1;
107
  <div class="wrap">
108
  <h2 style="margin-bottom:1em;">
109
  <?php _e( 'Audience > Export Contacts', 'email-subscribers' );
110
+ ES_Common::prepare_main_header_navigation( $audience_tab_main_navigation );
111
  ?>
112
  </h2>
113
  <div class="tool-box">
154
  $sql = "SELECT COUNT(email) FROM " . IG_CONTACTS_TABLE . " WHERE unsubscribed = 1 ";
155
  break;
156
 
157
+ case 'unconfirmed':
158
+ $sql = "SELECT count(distinct(contact_id)) FROM " . IG_LISTS_CONTACTS_TABLE . " WHERE status = 'unconfirmed'";
159
+ break;
160
+
161
  case 'registered':
162
  case 'commented':
163
  // Registered/ Commented Subscribers
206
 
207
  }
208
 
 
209
  public function generate_csv( $status = 'all' ) {
210
 
211
  global $wpdb;
214
  set_time_limit( IG_SET_TIME_LIMIT );
215
 
216
  $email_subscribe_table = IG_CONTACTS_TABLE;
217
+ $contact_lists_table = IG_LISTS_CONTACTS_TABLE;
218
+
219
  if ( 'active' === $status ) {
220
  $query = "SELECT `first_name`, `last_name`, `email`, `status`, `unsubscribed`, `created_at` FROM $email_subscribe_table WHERE unsubscribed = 0 OR unsubscribed IS NULL";
221
  } elseif ( 'inactive' === $status ) {
222
  $query = "SELECT `first_name`, `last_name`, `email`, `status`, `unsubscribed`, `created_at` FROM $email_subscribe_table WHERE unsubscribed = 1 ";
223
+ } elseif ( 'all' === $status ) {
224
  $query = "SELECT `first_name`, `last_name`, `email`, `status`, `unsubscribed`, `created_at` FROM $email_subscribe_table";
225
+ } elseif ( 'unconfirmed' === $status ) {
226
+ $query = "SELECT `first_name`, `last_name`, `email`, `status`, `unsubscribed`, `created_at` FROM $email_subscribe_table WHERE id IN (SELECT distinct(contact_id) FROM {$contact_lists_table} WHERE status = 'unconfirmed' )";
227
  }
228
 
229
  $subscribers = $wpdb->get_results( $query, ARRAY_A );
242
  $csv_output .= "\n";
243
 
244
  foreach ( $subscribers as $key => $subscriber ) {
245
+
246
+ $data['name'] = trim( $subscriber['first_name'] . ' ' . $subscriber['last_name'] );
247
+ $data['email'] = trim( $subscriber['email'] );
248
+
249
+ if ( 'unconfirmed' === $status ) {
250
+ $data['status'] = __( 'Unconfirmed', 'email-subscribers' );
251
+ } else {
252
+ $data['status'] = ( $subscriber['unsubscribed'] == 1 ) ? __( 'Unsubscribed', 'email-subscribers' ) : __( 'Subscribed', 'email-subscribers' );
253
+ }
254
  $data['created_at'] = $subscriber['created_at'];
255
 
256
  $csv_output .= implode( ',', $data );
257
  $csv_output .= "\n";
258
  }
 
259
  }
260
 
261
  return $csv_output;
includes/admin/class-es-handle-subscription.php CHANGED
@@ -121,6 +121,8 @@ class ES_Handle_Subscription {
121
  }
122
 
123
  $contact_id = ES_DB_Contacts::add_subscriber( $data );
 
 
124
  }
125
 
126
  if ( count( $this->list_ids ) > 0 ) {
121
  }
122
 
123
  $contact_id = ES_DB_Contacts::add_subscriber( $data );
124
+
125
+ do_action('ig_es_contact_added', $data);
126
  }
127
 
128
  if ( count( $this->list_ids ) > 0 ) {
includes/admin/class-es-newsletters.php CHANGED
@@ -58,8 +58,8 @@ class ES_Newsletters {
58
 
59
  self::es_send_email_callback( $data );
60
 
61
- $reports_url = admin_url('admin.php?page=es_reports');
62
- $message = __( sprintf( 'A new broadcast has been created successfully! Contacts from selected list will be notified within an hour. Want to notify now? <a href="%s" target="_blank">Click here</a>', $reports_url ), 'email-subscribers' );
63
 
64
  ES_Common::show_message( $message, 'success' );
65
  }
@@ -81,7 +81,7 @@ class ES_Newsletters {
81
  <?php settings_fields( 'es_newsletters_settings' ); ?>
82
  <?php do_settings_sections( 'newsletters_settings' ); ?>
83
  <div class="email-newsletters">
84
- <input type="submit" id="" name="es_send_email" value="<?php _e( 'Send Broadcast', 'email-subscribers') ?>" class="button button-primary">
85
  <input type="hidden" name="submitted" value="submitted">
86
  </div>
87
  </form>
58
 
59
  self::es_send_email_callback( $data );
60
 
61
+ $reports_url = admin_url( 'admin.php?page=es_reports' );
62
+ $message = __( sprintf( 'A new broadcast has been created successfully! Contacts from selected list will be notified within an hour. Want to notify now? <a href="%s" target="_blank">Click here</a>', $reports_url ), 'email-subscribers' );
63
 
64
  ES_Common::show_message( $message, 'success' );
65
  }
81
  <?php settings_fields( 'es_newsletters_settings' ); ?>
82
  <?php do_settings_sections( 'newsletters_settings' ); ?>
83
  <div class="email-newsletters">
84
+ <input type="submit" id="" name="es_send_email" value="<?php _e( 'Send Broadcast', 'email-subscribers' ) ?>" class="button button-primary">
85
  <input type="hidden" name="submitted" value="submitted">
86
  </div>
87
  </form>
includes/admin/class-es-subscribers-table.php CHANGED
@@ -15,6 +15,7 @@ class ES_Subscribers_Table extends WP_List_Table {
15
 
16
  public function __construct() {
17
 
 
18
  //set_error_handler(array( 'Email_General' , 'es_handle_error'));
19
  parent::__construct( array(
20
  'singular' => __( 'Contact', 'email-subscribers' ), //singular name of the listed records
15
 
16
  public function __construct() {
17
 
18
+
19
  //set_error_handler(array( 'Email_General' , 'es_handle_error'));
20
  parent::__construct( array(
21
  'singular' => __( 'Contact', 'email-subscribers' ), //singular name of the listed records
includes/admin/class-es-tools.php CHANGED
@@ -28,10 +28,10 @@ class ES_Tools {
28
  $email_response = '';
29
  $response = array();
30
  if ( ! empty( $email ) ) {
31
- $subject = 'Email Subscribers: ' . sprintf( esc_html__( 'Test email to %s', 'email-subscribers' ), $email );
32
- $content = self::get_email_message();
33
  $response = ES_Mailer::send( $email, $subject, $content );
34
- if($response['status'] === 'SUCCESS'){
35
  $response['message'] = __( 'Email has been sent. Please check your inbox', 'email-subscribers' );
36
  }
37
  // if ( $email_response ) {
28
  $email_response = '';
29
  $response = array();
30
  if ( ! empty( $email ) ) {
31
+ $subject = 'Email Subscribers: ' . sprintf( esc_html__( 'Test email to %s', 'email-subscribers' ), $email );
32
+ $content = self::get_email_message();
33
  $response = ES_Mailer::send( $email, $subject, $content );
34
+ if ( $response['status'] === 'SUCCESS' ) {
35
  $response['message'] = __( 'Email has been sent. Please check your inbox', 'email-subscribers' );
36
  }
37
  // if ( $email_response ) {
includes/class-email-subscribers.php CHANGED
@@ -72,11 +72,12 @@ class Email_Subscribers {
72
  * @since 4.0
73
  */
74
  public function __construct() {
 
75
 
76
  require_once plugin_dir_path( __FILE__ ) . 'class-email-subscribers-activator.php';
77
  require_once plugin_dir_path( __FILE__ ) . 'class-email-subscribers-deactivator.php';
78
 
79
- add_action( 'admin_notices', array( $this, 'add_version_notice' ) );
80
  add_action( 'admin_init', array( &$this, 'es_dismiss_admin_notice' ) );
81
  if ( ! post_type_exists( 'es_template' ) ) {
82
  add_action( 'init', array( 'Email_Subscribers_Activator', 'register_email_templates' ) );
@@ -90,22 +91,37 @@ class Email_Subscribers {
90
  $this->define_admin_hooks();
91
  $this->define_public_hooks();
92
 
93
- if(is_admin()) {
94
- new IG_Deactivation_Survey('Email Subscribers', 'email-subscribers', 'ig_es');
95
- }
 
 
96
 
97
  add_action( 'widgets_init', array( $this, 'register_es_widget' ) );
98
  add_filter( 'cron_schedules', array( $this, 'es_add_cron_interval' ) );
99
  }
100
 
101
- public function add_version_notice() {
 
 
 
 
 
 
 
 
 
 
 
102
 
103
- //Email Subscribers Pro update notice
104
- $active_plugins = get_option( 'active_plugins', array() );
105
- if ( is_multisite() ) {
106
- $active_plugins = array_merge( $active_plugins, get_site_option( 'active_sitewide_plugins', array() ) );
107
  }
108
- if ( is_admin() && ( in_array( 'email-subscribers-premium/email-subscribers-premium.php', $active_plugins ) || array_key_exists( 'email-subscribers-premium/email-subscribers-premium.php', $active_plugins ) ) ) {
 
 
 
 
109
  $es_pro_plugin_meta_data = get_plugin_data( WP_PLUGIN_DIR . '/email-subscribers-premium/email-subscribers-premium.php' );
110
  $es_pro_plugin_version = $es_pro_plugin_meta_data['Version'];
111
 
@@ -119,12 +135,29 @@ class Email_Subscribers {
119
  <?php
120
  return;
121
  }
122
- if ( is_admin() && ! empty( $es_pro_plugin_version ) && version_compare( $es_pro_plugin_version, '4.1.1' , '<' ) ) {
123
- $url = admin_url( "plugins.php?plugin_status=upgrade" );
124
  $es_upgrade_text = __( 'We have released a recommended update of Email subscribers Premium. So kindly ', 'email-subscribers-premium' ) . '<a href=' . $url . ' target="_blank" style="cursor:pointer">' . __( "update to the latest version", "email-subscribers-premium" ) . '</a>' . __( " right now", "email-subscribers-premium" );
125
  echo '<div class="notice notice-warning" style="background-color: #FFF;"><p style="letter-spacing: 0.6px;">' . $es_upgrade_text . '</p></div>';
126
  }
127
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
128
  //cron notice
129
  $notice_option = get_option( 'ig_es_wp_cron_notice' );
130
 
@@ -141,15 +174,28 @@ class Email_Subscribers {
141
  echo '<div class="notice notice-warning" style="background-color: #FFF;"><p style="letter-spacing: 0.6px;">' . $disable_wp_cron_notice . '<a style="float:right" class="es-admin-btn es-admin-btn-secondary " href="' . admin_url() . '?es_dismiss_admin_notice=1&option_name=wp_cron_notice">' . __( 'OK, I Got it!',
142
  'email-subscribers' ) . '</a></p></div>';
143
  }
 
 
144
  }
145
 
146
  public function es_dismiss_admin_notice() {
147
  if ( isset( $_GET['es_dismiss_admin_notice'] ) && $_GET['es_dismiss_admin_notice'] == '1' && isset( $_GET['option_name'] ) ) {
148
  $option_name = sanitize_text_field( $_GET['option_name'] );
149
  update_option( 'ig_es_' . $option_name, 'yes' );
150
-
151
- $referer = wp_get_referer();
152
- wp_safe_redirect( $referer );
 
 
 
 
 
 
 
 
 
 
 
153
  exit();
154
  }
155
  }
@@ -308,20 +354,21 @@ class Email_Subscribers {
308
 
309
  'includes/pro-features.php',
310
 
311
- // Feedback
312
- 'includes/feedback/class-ig-tracker.php',
313
- 'includes/feedback/class-ig-deactivation-survey.php'
 
314
  );
315
 
316
  foreach ( $required_files as $file ) {
317
  $file_path = plugin_dir_path( dirname( __FILE__ ) ) . $file;
318
 
319
- if(is_file($file_path)) {
320
- require_once $file_path;
321
- } else {
322
- echo $file_path;
323
- die('Not Found');
324
- }
325
  }
326
 
327
  add_shortcode( 'email-subscribers', array( 'ES_Shortcode', 'render_es_subscription_shortcode' ) );
@@ -359,6 +406,7 @@ class Email_Subscribers {
359
  $this->loader->add_action( 'plugins_loaded', $plugin_admin, 'plugins_loaded' );
360
  $this->loader->add_filter( 'ig_es_lite_do_send', $plugin_admin, 'do_send', 10, 2 );
361
 
 
362
  //$this->loader->add_filter( 'ig_es_blocked_domains', $plugin_admin, 'blocked_domains', 10, 1 );
363
  //$this->loader->add_filter( 'ig_es_whitelist_ips', $plugin_admin, 'whitelist_ips', 10, 1 );
364
  //$this->loader->add_filter( 'ig_es_blacklist_ips', $plugin_admin, 'blacklist_ips', 10, 1 );
@@ -381,7 +429,6 @@ class Email_Subscribers {
381
  $this->loader->add_action( 'init', $plugin_public, 'es_email_subscribe_init' );
382
  $this->loader->add_action( 'ig_es_add_contact', $plugin_public, 'add_contact', 10, 2 );
383
 
384
-
385
  }
386
 
387
  /**
@@ -397,8 +444,8 @@ class Email_Subscribers {
397
  * The name of the plugin used to uniquely identify it within the context of
398
  * WordPress and to define internationalization functionality.
399
  *
400
- * @since 4.0
401
  * @return string The name of the plugin.
 
402
  */
403
  public function get_email_subscribers() {
404
  return $this->email_subscribers;
@@ -407,8 +454,8 @@ class Email_Subscribers {
407
  /**
408
  * The reference to the class that orchestrates the hooks with the plugin.
409
  *
410
- * @since 4.0
411
  * @return Email_Subscribers_Loader Orchestrates the hooks of the plugin.
 
412
  */
413
  public function get_loader() {
414
  return $this->loader;
@@ -417,8 +464,8 @@ class Email_Subscribers {
417
  /**
418
  * Retrieve the version number of the plugin.
419
  *
420
- * @since 4.0
421
  * @return string The version number of the plugin.
 
422
  */
423
  public function get_version() {
424
  return $this->version;
72
  * @since 4.0
73
  */
74
  public function __construct() {
75
+ global $ig_es_feedback;
76
 
77
  require_once plugin_dir_path( __FILE__ ) . 'class-email-subscribers-activator.php';
78
  require_once plugin_dir_path( __FILE__ ) . 'class-email-subscribers-deactivator.php';
79
 
80
+ add_action( 'admin_notices', array( $this, 'add_admin_notice' ) );
81
  add_action( 'admin_init', array( &$this, 'es_dismiss_admin_notice' ) );
82
  if ( ! post_type_exists( 'es_template' ) ) {
83
  add_action( 'init', array( 'Email_Subscribers_Activator', 'register_email_templates' ) );
91
  $this->define_admin_hooks();
92
  $this->define_public_hooks();
93
 
94
+
95
+ if ( is_admin() ) {
96
+ $ig_es_feedback = new IG_Feedback_V_1_0_1( 'Email Subscribers', 'email-subscribers', 'ig_es', 'esfree.', false );
97
+ $ig_es_feedback->render_deactivate_feedback();
98
+ }
99
 
100
  add_action( 'widgets_init', array( $this, 'register_es_widget' ) );
101
  add_filter( 'cron_schedules', array( $this, 'es_add_cron_interval' ) );
102
  }
103
 
104
+ public function add_admin_notice() {
105
+ $screen = get_current_screen();
106
+ $screen_id = $screen ? $screen->id : '';
107
+ $show_on_screens = array(
108
+ 'toplevel_page_es_dashboard',
109
+ 'email-subscribers_page_es_subscribers',
110
+ 'email-subscribers_page_es_forms',
111
+ 'email-subscribers_page_es_campaigns',
112
+ 'email-subscribers_page_es_reports',
113
+ 'email-subscribers_page_es_settings',
114
+ 'email-subscribers_page_es_general_information',
115
+ );
116
 
117
+ if ( ! in_array( $screen_id, $show_on_screens, true ) ) {
118
+ return;
 
 
119
  }
120
+
121
+ //Email Subscribers Pro update notice
122
+ $active_plugins = IG_Tracker_V_1_0_1::get_active_plugins();
123
+
124
+ if ( is_admin() && in_array( 'email-subscribers-premium/email-subscribers-premium.php', $active_plugins ) ) {
125
  $es_pro_plugin_meta_data = get_plugin_data( WP_PLUGIN_DIR . '/email-subscribers-premium/email-subscribers-premium.php' );
126
  $es_pro_plugin_version = $es_pro_plugin_meta_data['Version'];
127
 
135
  <?php
136
  return;
137
  }
138
+ if ( is_admin() && ! empty( $es_pro_plugin_version ) && version_compare( $es_pro_plugin_version, '4.1.1', '<' ) ) {
139
+ $url = admin_url( "plugins.php?plugin_status=upgrade" );
140
  $es_upgrade_text = __( 'We have released a recommended update of Email subscribers Premium. So kindly ', 'email-subscribers-premium' ) . '<a href=' . $url . ' target="_blank" style="cursor:pointer">' . __( "update to the latest version", "email-subscribers-premium" ) . '</a>' . __( " right now", "email-subscribers-premium" );
141
  echo '<div class="notice notice-warning" style="background-color: #FFF;"><p style="letter-spacing: 0.6px;">' . $es_upgrade_text . '</p></div>';
142
  }
143
  }
144
+
145
+ $all_plugins = IG_Tracker_V_1_0_1::get_plugins();
146
+
147
+ if ( ! in_array( 'email-subscribers-premium/email-subscribers-premium.php', $all_plugins ) ) {
148
+
149
+ // admin starter announcement
150
+ $upsale_notice_option = get_option( 'ig_es_redirect_upsale_notice', 'no' );
151
+ $dismiss_notice_option = get_option( 'ig_es_dismiss_upsale_notice', 'no' );
152
+ if ( 'yes' !== $upsale_notice_option && 'yes' !== $dismiss_notice_option ) {
153
+ $text_1 = __( 'Grow your audience. Stop worrying about email.' );
154
+ echo '<div class="notice notice-warning" style="background: #ffefd5;">
155
+ <p style="font-size: 1.1em; "><span class="dashicons dashicons-megaphone" style="color: #ff0000;"></span>&nbsp;&nbsp;' . $text_1 . '&nbsp;&nbsp;<strong><a href="?es_dismiss_admin_notice=1&option_name=redirect_upsale_notice" target="_blank" >' . __( 'Get Starter Plan', 'email-subscribers' ) . '</a></strong>
156
+ <a style="float:right" class="ig-admin-btn ig-admin-btn-secondary" href="?es_dismiss_admin_notice=1&option_name=dismiss_upsale_notice">' . __( 'No, I don\'t want it', true ) . '</a>
157
+ </p>
158
+ </div>';
159
+ }
160
+ }
161
  //cron notice
162
  $notice_option = get_option( 'ig_es_wp_cron_notice' );
163
 
174
  echo '<div class="notice notice-warning" style="background-color: #FFF;"><p style="letter-spacing: 0.6px;">' . $disable_wp_cron_notice . '<a style="float:right" class="es-admin-btn es-admin-btn-secondary " href="' . admin_url() . '?es_dismiss_admin_notice=1&option_name=wp_cron_notice">' . __( 'OK, I Got it!',
175
  'email-subscribers' ) . '</a></p></div>';
176
  }
177
+
178
+
179
  }
180
 
181
  public function es_dismiss_admin_notice() {
182
  if ( isset( $_GET['es_dismiss_admin_notice'] ) && $_GET['es_dismiss_admin_notice'] == '1' && isset( $_GET['option_name'] ) ) {
183
  $option_name = sanitize_text_field( $_GET['option_name'] );
184
  update_option( 'ig_es_' . $option_name, 'yes' );
185
+ if ( in_array( $option_name, array( 'redirect_upsale_notice', 'dismiss_upsale_notice', 'dismiss_star_notice', 'star_notice_done' ) ) ) {
186
+ update_option( 'ig_es_' . $option_name . '_date', ig_get_current_date_time() );
187
+ }
188
+ if ( $option_name === 'star_notice_done' ) {
189
+ header( "Location: https://wordpress.org/support/plugin/email-subscribers/reviews/" );
190
+ exit();
191
+ }
192
+ if ( $option_name === 'redirect_upsale_notice' ) {
193
+ header( "Location: https://www.icegram.com/email-subscribers-starter-plan-pricing/?utm_source=es&utm_medium=es_upsale_banner&utm_campaign=es_upsale" );
194
+ exit();
195
+ } else {
196
+ $referer = wp_get_referer();
197
+ wp_safe_redirect( $referer );
198
+ }
199
  exit();
200
  }
201
  }
354
 
355
  'includes/pro-features.php',
356
 
357
+ // Feedback
358
+ 'includes/feedback/class-ig-tracker-v-1-0-1.php',
359
+ 'includes/feedback/class-ig-feedback-v-1-0-1.php',
360
+ 'includes/feedback.php'
361
  );
362
 
363
  foreach ( $required_files as $file ) {
364
  $file_path = plugin_dir_path( dirname( __FILE__ ) ) . $file;
365
 
366
+ if ( is_file( $file_path ) ) {
367
+ require_once $file_path;
368
+ } else {
369
+ echo $file_path;
370
+ die( 'Not Found' );
371
+ }
372
  }
373
 
374
  add_shortcode( 'email-subscribers', array( 'ES_Shortcode', 'render_es_subscription_shortcode' ) );
406
  $this->loader->add_action( 'plugins_loaded', $plugin_admin, 'plugins_loaded' );
407
  $this->loader->add_filter( 'ig_es_lite_do_send', $plugin_admin, 'do_send', 10, 2 );
408
 
409
+
410
  //$this->loader->add_filter( 'ig_es_blocked_domains', $plugin_admin, 'blocked_domains', 10, 1 );
411
  //$this->loader->add_filter( 'ig_es_whitelist_ips', $plugin_admin, 'whitelist_ips', 10, 1 );
412
  //$this->loader->add_filter( 'ig_es_blacklist_ips', $plugin_admin, 'blacklist_ips', 10, 1 );
429
  $this->loader->add_action( 'init', $plugin_public, 'es_email_subscribe_init' );
430
  $this->loader->add_action( 'ig_es_add_contact', $plugin_public, 'add_contact', 10, 2 );
431
 
 
432
  }
433
 
434
  /**
444
  * The name of the plugin used to uniquely identify it within the context of
445
  * WordPress and to define internationalization functionality.
446
  *
 
447
  * @return string The name of the plugin.
448
+ * @since 4.0
449
  */
450
  public function get_email_subscribers() {
451
  return $this->email_subscribers;
454
  /**
455
  * The reference to the class that orchestrates the hooks with the plugin.
456
  *
 
457
  * @return Email_Subscribers_Loader Orchestrates the hooks of the plugin.
458
+ * @since 4.0
459
  */
460
  public function get_loader() {
461
  return $this->loader;
464
  /**
465
  * Retrieve the version number of the plugin.
466
  *
 
467
  * @return string The version number of the plugin.
468
+ * @since 4.0
469
  */
470
  public function get_version() {
471
  return $this->version;
includes/class-es-common.php CHANGED
@@ -848,33 +848,102 @@ Class ES_Common {
848
  $is_box_shadow = $info['box_shadow'];
849
 
850
  $div_class = 'ig-es-information-box';
851
- if($is_center) {
852
  $div_class .= ' ig-es-center';
853
- }
854
 
855
- if($is_box_shadow) {
856
  $div_class .= ' ig-es-box-shadow';
857
- }
858
 
859
- if($type) {
860
- $div_class .= ' ig-es-' .$type;
861
- }
862
 
863
  ?>
864
 
865
  <div class="<?php echo $div_class; ?>">
866
  <div class="ig-vertical-align">
867
- <?php if($show_icon) { ?>
868
  <div class="ig-es-icon text-center">
869
  <span class="dashicons ig-es-icon-<?php echo $type; ?>"></span>
870
  </div>
871
- <?php } ?>
872
  <div class="ig-es-info-message">
873
- <?php echo $content_html; ?>
874
  </div>
875
  </div>
876
  </div>
877
 
878
  <?php
879
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
880
  }
848
  $is_box_shadow = $info['box_shadow'];
849
 
850
  $div_class = 'ig-es-information-box';
851
+ if ( $is_center ) {
852
  $div_class .= ' ig-es-center';
853
+ }
854
 
855
+ if ( $is_box_shadow ) {
856
  $div_class .= ' ig-es-box-shadow';
857
+ }
858
 
859
+ if ( $type ) {
860
+ $div_class .= ' ig-es-' . $type;
861
+ }
862
 
863
  ?>
864
 
865
  <div class="<?php echo $div_class; ?>">
866
  <div class="ig-vertical-align">
867
+ <?php if ( $show_icon ) { ?>
868
  <div class="ig-es-icon text-center">
869
  <span class="dashicons ig-es-icon-<?php echo $type; ?>"></span>
870
  </div>
871
+ <?php } ?>
872
  <div class="ig-es-info-message">
873
+ <?php echo $content_html; ?>
874
  </div>
875
  </div>
876
  </div>
877
 
878
  <?php
879
  }
880
+
881
+ /**
882
+ * Render Quick Feedback Widget
883
+ *
884
+ * @param $params
885
+ *
886
+ */
887
+ public static function render_feedback_widget( $params ) {
888
+ global $ig_es_feedback;
889
+
890
+ $feedback = $ig_es_feedback;
891
+
892
+ $default_params = array(
893
+ 'set_transient' => true,
894
+ 'force' => false
895
+ );
896
+
897
+ $params = wp_parse_args($params, $default_params);
898
+
899
+ if ( ! empty( $params['event'] ) ) {
900
+
901
+ $event = $feedback->event_prefix . $params['event'];
902
+ $force = ! empty( $params['force'] ) ? $params['force'] : false;
903
+
904
+ $can_show = false;
905
+
906
+ if ( $force ) {
907
+ $can_show = true;
908
+ } else {
909
+ if ( ! $feedback->is_event_transient_set( $event ) ) {
910
+ $can_show = true;
911
+
912
+ $feedback_data = $feedback->get_event_feedback_data( $feedback->plugin_abbr, $event );
913
+ if ( count( $feedback_data ) > 0 ) {
914
+ $feedback_data = array_reverse( $feedback_data );
915
+ $last_feedback_given_on = $feedback_data[0]['created_on'];
916
+ if ( strtotime( $last_feedback_given_on ) > strtotime( '-45 days' ) ) {
917
+ $can_show = false;
918
+ }
919
+ }
920
+ }
921
+ }
922
+
923
+ if ( $can_show ) {
924
+ if ( 'star' === $params['type'] ) {
925
+ $feedback->render_stars( $params );
926
+ } elseif ( 'emoji' === $params['type'] ) {
927
+ $feedback->render_emoji( $params );
928
+ }
929
+ }
930
+ }
931
+
932
+ }
933
+
934
+ public static function get_ig_es_meta_info() {
935
+
936
+ $total_contacts = ES_DB_Contacts::get_total_subscribers();
937
+ $total_newsletters = ES_DB_Campaigns::get_total_campaigns_by_type( 'newsletter' );
938
+ $total_post_notifications = ES_DB_Campaigns::get_total_campaigns_by_type( 'post_notification' );
939
+
940
+ $meta_info = array(
941
+ 'total_contacts' => $total_contacts,
942
+ 'total_newsletters' => $total_newsletters,
943
+ 'total_post_notifications' => $total_post_notifications
944
+ );
945
+
946
+ return $meta_info;
947
+ }
948
+
949
  }
includes/class-es-install.php CHANGED
@@ -211,7 +211,6 @@ class ES_Install {
211
  self::create_default_form();
212
 
213
  self::$logger->info( 'Installation Complete......' );
214
-
215
  }
216
 
217
  self::maybe_update_db_version();
@@ -397,6 +396,7 @@ class ES_Install {
397
  'ig_es_blocked_domains' => array( 'default' => 'mail.ru' ),
398
  'ig_es_disable_wp_cron' => array( 'default' => 'no' ),
399
  'ig_es_track_email_opens' => array( 'default' => 'yes' ),
 
400
  );
401
 
402
  return $options;
@@ -702,17 +702,18 @@ class ES_Install {
702
  // Newsletter Send
703
 
704
  $email_template = ES_Common::convert_es_templates( $sample, $admin_name, $admin_email, $email_created );
705
- $response = ES_Mailer::send( $admin_email, $title, $email_template );
706
- if( !empty($response) && $response['status'] === 'SUCCESS'){
707
  //update sent details
708
- $emails = ES_DB_Sending_Queue::get_emails_to_be_sent_by_hash( $guid, 5 );
709
- $ids = array();
710
  foreach ( $emails as $email ) {
711
  $ids[] = $email['id'];
712
  }
713
  ES_DB_Sending_Queue::update_sent_status( $ids, 'Sent' );
714
  ES_DB_Mailing_Queue::update_sent_status( $guid, 'Sent' );
715
  }
 
716
  return $response;
717
  }
718
 
@@ -823,11 +824,11 @@ class ES_Install {
823
 
824
  // Post Notification Send Send
825
  $email_template = ES_Common::convert_es_templates( $content, $admin_name, $admin_email, $email_created );
826
- $response = ES_Mailer::send( $admin_email, $title, $email_template );
827
- if( !empty($response) && $response['status'] === 'SUCCESS'){
828
  //update sent details
829
- $emails = ES_DB_Sending_Queue::get_emails_to_be_sent_by_hash( $guid, 5 );
830
- $ids = array();
831
  foreach ( $emails as $email ) {
832
  $ids[] = $email['id'];
833
  }
@@ -835,6 +836,7 @@ class ES_Install {
835
  ES_DB_Mailing_Queue::update_sent_status( $guid, 'Sent' );
836
  //change post notification from test to main
837
  }
 
838
  return $response;
839
  }
840
  }
211
  self::create_default_form();
212
 
213
  self::$logger->info( 'Installation Complete......' );
 
214
  }
215
 
216
  self::maybe_update_db_version();
396
  'ig_es_blocked_domains' => array( 'default' => 'mail.ru' ),
397
  'ig_es_disable_wp_cron' => array( 'default' => 'no' ),
398
  'ig_es_track_email_opens' => array( 'default' => 'yes' ),
399
+ 'ig_es_installed_on' => array( 'default' => ig_get_current_date_time(), 'old_option' => '' ),
400
  );
401
 
402
  return $options;
702
  // Newsletter Send
703
 
704
  $email_template = ES_Common::convert_es_templates( $sample, $admin_name, $admin_email, $email_created );
705
+ $response = ES_Mailer::send( $admin_email, $title, $email_template );
706
+ if ( ! empty( $response ) && $response['status'] === 'SUCCESS' ) {
707
  //update sent details
708
+ $emails = ES_DB_Sending_Queue::get_emails_to_be_sent_by_hash( $guid, 5 );
709
+ $ids = array();
710
  foreach ( $emails as $email ) {
711
  $ids[] = $email['id'];
712
  }
713
  ES_DB_Sending_Queue::update_sent_status( $ids, 'Sent' );
714
  ES_DB_Mailing_Queue::update_sent_status( $guid, 'Sent' );
715
  }
716
+
717
  return $response;
718
  }
719
 
824
 
825
  // Post Notification Send Send
826
  $email_template = ES_Common::convert_es_templates( $content, $admin_name, $admin_email, $email_created );
827
+ $response = ES_Mailer::send( $admin_email, $title, $email_template );
828
+ if ( ! empty( $response ) && $response['status'] === 'SUCCESS' ) {
829
  //update sent details
830
+ $emails = ES_DB_Sending_Queue::get_emails_to_be_sent_by_hash( $guid, 5 );
831
+ $ids = array();
832
  foreach ( $emails as $email ) {
833
  $ids[] = $email['id'];
834
  }
836
  ES_DB_Mailing_Queue::update_sent_status( $guid, 'Sent' );
837
  //change post notification from test to main
838
  }
839
+
840
  return $response;
841
  }
842
  }
includes/db/class-es-db-campaigns.php CHANGED
@@ -331,11 +331,21 @@ class ES_DB_Campaigns {
331
 
332
  global $wpdb;
333
 
334
- $query = "SELECT count(*) as total_campaigns FROM " . IG_CAMPAIGNS_TABLE ." WHERE deleted_at IS NULL OR deleted_at = '0000-00-00 00:00:00'" ;
335
- $campaigns = $wpdb->get_var( $query);
336
 
337
  return $campaigns;
338
 
339
  }
340
 
 
 
 
 
 
 
 
 
 
 
341
  }
331
 
332
  global $wpdb;
333
 
334
+ $query = "SELECT count(*) as total_campaigns FROM " . IG_CAMPAIGNS_TABLE . " WHERE deleted_at IS NULL OR deleted_at = '0000-00-00 00:00:00'";
335
+ $campaigns = $wpdb->get_var( $query );
336
 
337
  return $campaigns;
338
 
339
  }
340
 
341
+ public static function get_total_campaigns_by_type( $type = 'newsletter' ) {
342
+ global $wpdb;
343
+
344
+ $query = "SELECT count(*) as total_campaigns FROM " . IG_CAMPAIGNS_TABLE . " WHERE type = %s AND (deleted_at IS NULL OR deleted_at = '0000-00-00 00:00:00')";
345
+ $query = $wpdb->prepare( $query, $type );
346
+ $campaigns = $wpdb->get_var( $query );
347
+
348
+ return $campaigns;
349
+ }
350
+
351
  }
includes/feedback.php ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Get additional system & plugin specific information for feedback
5
+ *
6
+ */
7
+ if ( ! function_exists( 'ig_es_get_additional_info' ) ) {
8
+
9
+ function ig_es_get_additional_info( $additional_info, $system_info = false ) {
10
+
11
+ $additional_info['version'] = ES_PLUGIN_VERSION;
12
+
13
+ if ( $system_info ) {
14
+
15
+ $additional_info['active_plugins'] = IG_Tracker_V_1_0_1::get_active_plugins();
16
+ $additional_info['inactive_plugins'] = IG_Tracker_V_1_0_1::get_inactive_plugins();
17
+ $additional_info['current_theme'] = IG_Tracker_V_1_0_1::get_current_theme_info();
18
+ $additional_info['wp_info'] = IG_Tracker_V_1_0_1::get_wp_info();
19
+ $additional_info['server_info'] = IG_Tracker_V_1_0_1::get_server_info();
20
+
21
+ // ES Specific information
22
+ $additional_info['plugin_meta_info'] = ES_Common::get_ig_es_meta_info();
23
+ }
24
+
25
+ return $additional_info;
26
+
27
+ }
28
+
29
+ }
30
+
31
+
32
+ add_filter( 'ig_es_additional_feedback_meta_info', 'ig_es_get_additional_info', 10, 2 );
33
+
34
+
35
+ function ig_es_render_feedback_widget() {
36
+
37
+ if ( is_admin() ) {
38
+ global $ig_es_feedback;
39
+
40
+ if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
41
+ return;
42
+ }
43
+ $screen = get_current_screen();
44
+ $screen_id = $screen ? $screen->id : '';
45
+
46
+ $show_on_screens = array(
47
+ 'email-subscribers_page_es_subscribers',
48
+ 'email-subscribers_page_es_forms',
49
+ 'email-subscribers_page_es_campaigns',
50
+ 'email-subscribers_page_es_reports',
51
+ 'email-subscribers_page_es_settings',
52
+ );
53
+
54
+ if ( ! in_array( $screen_id, $show_on_screens, true ) ) {
55
+ return;
56
+ }
57
+
58
+ if ( ! $ig_es_feedback->can_show_feedback_widget() ) {
59
+ return;
60
+ }
61
+
62
+ $event = 'plugin.experience';
63
+ if ( ! $ig_es_feedback->is_event_transient_set( $ig_es_feedback->event_prefix . $event ) ) {
64
+
65
+ $total_contacts = ES_DB_Contacts::get_total_subscribers();
66
+
67
+ if ( $total_contacts > 10 ) {
68
+
69
+ $params = array(
70
+ 'type' => 'emoji',
71
+ 'event' => $event,
72
+ 'title' => "How's your experience with Email Subscribers?",
73
+ 'position' => 'center',
74
+ 'width' => 600,
75
+ //'force' => true,
76
+ //'set_transient' => false
77
+ );
78
+
79
+ ES_Common::render_feedback_widget( $params );
80
+ }
81
+ }
82
+
83
+ }
84
+
85
+ }
86
+
87
+ add_action( 'admin_footer', 'ig_es_render_feedback_widget' );
includes/feedback/assets/css/animate.min.css ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ @charset "UTF-8";
2
+
3
+ /*!
4
+ * animate.css -http://daneden.me/animate
5
+ * Version - 3.6.0
6
+ * Licensed under the MIT license - http://opensource.org/licenses/MIT
7
+ *
8
+ * Copyright (c) 2018 Daniel Eden
9
+ */
10
+
11
+ .animated{-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-fill-mode:both;animation-fill-mode:both}.animated.infinite{-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}@-webkit-keyframes bounce{0%,20%,53%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1);-webkit-transform:translateZ(0);transform:translateZ(0)}40%,43%{-webkit-animation-timing-function:cubic-bezier(.755,.05,.855,.06);animation-timing-function:cubic-bezier(.755,.05,.855,.06);-webkit-transform:translate3d(0,-30px,0);transform:translate3d(0,-30px,0)}70%{-webkit-animation-timing-function:cubic-bezier(.755,.05,.855,.06);animation-timing-function:cubic-bezier(.755,.05,.855,.06);-webkit-transform:translate3d(0,-15px,0);transform:translate3d(0,-15px,0)}90%{-webkit-transform:translate3d(0,-4px,0);transform:translate3d(0,-4px,0)}}@keyframes bounce{0%,20%,53%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1);-webkit-transform:translateZ(0);transform:translateZ(0)}40%,43%{-webkit-animation-timing-function:cubic-bezier(.755,.05,.855,.06);animation-timing-function:cubic-bezier(.755,.05,.855,.06);-webkit-transform:translate3d(0,-30px,0);transform:translate3d(0,-30px,0)}70%{-webkit-animation-timing-function:cubic-bezier(.755,.05,.855,.06);animation-timing-function:cubic-bezier(.755,.05,.855,.06);-webkit-transform:translate3d(0,-15px,0);transform:translate3d(0,-15px,0)}90%{-webkit-transform:translate3d(0,-4px,0);transform:translate3d(0,-4px,0)}}.bounce{-webkit-animation-name:bounce;animation-name:bounce;-webkit-transform-origin:center bottom;transform-origin:center bottom}@-webkit-keyframes flash{0%,50%,to{opacity:1}25%,75%{opacity:0}}@keyframes flash{0%,50%,to{opacity:1}25%,75%{opacity:0}}.flash{-webkit-animation-name:flash;animation-name:flash}@-webkit-keyframes pulse{0%{-webkit-transform:scaleX(1);transform:scaleX(1)}50%{-webkit-transform:scale3d(1.05,1.05,1.05);transform:scale3d(1.05,1.05,1.05)}to{-webkit-transform:scaleX(1);transform:scaleX(1)}}@keyframes pulse{0%{-webkit-transform:scaleX(1);transform:scaleX(1)}50%{-webkit-transform:scale3d(1.05,1.05,1.05);transform:scale3d(1.05,1.05,1.05)}to{-webkit-transform:scaleX(1);transform:scaleX(1)}}.pulse{-webkit-animation-name:pulse;animation-name:pulse}@-webkit-keyframes rubberBand{0%{-webkit-transform:scaleX(1);transform:scaleX(1)}30%{-webkit-transform:scale3d(1.25,.75,1);transform:scale3d(1.25,.75,1)}40%{-webkit-transform:scale3d(.75,1.25,1);transform:scale3d(.75,1.25,1)}50%{-webkit-transform:scale3d(1.15,.85,1);transform:scale3d(1.15,.85,1)}65%{-webkit-transform:scale3d(.95,1.05,1);transform:scale3d(.95,1.05,1)}75%{-webkit-transform:scale3d(1.05,.95,1);transform:scale3d(1.05,.95,1)}to{-webkit-transform:scaleX(1);transform:scaleX(1)}}@keyframes rubberBand{0%{-webkit-transform:scaleX(1);transform:scaleX(1)}30%{-webkit-transform:scale3d(1.25,.75,1);transform:scale3d(1.25,.75,1)}40%{-webkit-transform:scale3d(.75,1.25,1);transform:scale3d(.75,1.25,1)}50%{-webkit-transform:scale3d(1.15,.85,1);transform:scale3d(1.15,.85,1)}65%{-webkit-transform:scale3d(.95,1.05,1);transform:scale3d(.95,1.05,1)}75%{-webkit-transform:scale3d(1.05,.95,1);transform:scale3d(1.05,.95,1)}to{-webkit-transform:scaleX(1);transform:scaleX(1)}}.rubberBand{-webkit-animation-name:rubberBand;animation-name:rubberBand}@-webkit-keyframes shake{0%,to{-webkit-transform:translateZ(0);transform:translateZ(0)}10%,30%,50%,70%,90%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}20%,40%,60%,80%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}}@keyframes shake{0%,to{-webkit-transform:translateZ(0);transform:translateZ(0)}10%,30%,50%,70%,90%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}20%,40%,60%,80%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}}.shake{-webkit-animation-name:shake;animation-name:shake}@-webkit-keyframes headShake{0%{-webkit-transform:translateX(0);transform:translateX(0)}6.5%{-webkit-transform:translateX(-6px) rotateY(-9deg);transform:translateX(-6px) rotateY(-9deg)}18.5%{-webkit-transform:translateX(5px) rotateY(7deg);transform:translateX(5px) rotateY(7deg)}31.5%{-webkit-transform:translateX(-3px) rotateY(-5deg);transform:translateX(-3px) rotateY(-5deg)}43.5%{-webkit-transform:translateX(2px) rotateY(3deg);transform:translateX(2px) rotateY(3deg)}50%{-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes headShake{0%{-webkit-transform:translateX(0);transform:translateX(0)}6.5%{-webkit-transform:translateX(-6px) rotateY(-9deg);transform:translateX(-6px) rotateY(-9deg)}18.5%{-webkit-transform:translateX(5px) rotateY(7deg);transform:translateX(5px) rotateY(7deg)}31.5%{-webkit-transform:translateX(-3px) rotateY(-5deg);transform:translateX(-3px) rotateY(-5deg)}43.5%{-webkit-transform:translateX(2px) rotateY(3deg);transform:translateX(2px) rotateY(3deg)}50%{-webkit-transform:translateX(0);transform:translateX(0)}}.headShake{-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;-webkit-animation-name:headShake;animation-name:headShake}@-webkit-keyframes swing{20%{-webkit-transform:rotate(15deg);transform:rotate(15deg)}40%{-webkit-transform:rotate(-10deg);transform:rotate(-10deg)}60%{-webkit-transform:rotate(5deg);transform:rotate(5deg)}80%{-webkit-transform:rotate(-5deg);transform:rotate(-5deg)}to{-webkit-transform:rotate(0deg);transform:rotate(0deg)}}@keyframes swing{20%{-webkit-transform:rotate(15deg);transform:rotate(15deg)}40%{-webkit-transform:rotate(-10deg);transform:rotate(-10deg)}60%{-webkit-transform:rotate(5deg);transform:rotate(5deg)}80%{-webkit-transform:rotate(-5deg);transform:rotate(-5deg)}to{-webkit-transform:rotate(0deg);transform:rotate(0deg)}}.swing{-webkit-transform-origin:top center;transform-origin:top center;-webkit-animation-name:swing;animation-name:swing}@-webkit-keyframes tada{0%{-webkit-transform:scaleX(1);transform:scaleX(1)}10%,20%{-webkit-transform:scale3d(.9,.9,.9) rotate(-3deg);transform:scale3d(.9,.9,.9) rotate(-3deg)}30%,50%,70%,90%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate(3deg);transform:scale3d(1.1,1.1,1.1) rotate(3deg)}40%,60%,80%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate(-3deg);transform:scale3d(1.1,1.1,1.1) rotate(-3deg)}to{-webkit-transform:scaleX(1);transform:scaleX(1)}}@keyframes tada{0%{-webkit-transform:scaleX(1);transform:scaleX(1)}10%,20%{-webkit-transform:scale3d(.9,.9,.9) rotate(-3deg);transform:scale3d(.9,.9,.9) rotate(-3deg)}30%,50%,70%,90%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate(3deg);transform:scale3d(1.1,1.1,1.1) rotate(3deg)}40%,60%,80%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate(-3deg);transform:scale3d(1.1,1.1,1.1) rotate(-3deg)}to{-webkit-transform:scaleX(1);transform:scaleX(1)}}.tada{-webkit-animation-name:tada;animation-name:tada}@-webkit-keyframes wobble{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}15%{-webkit-transform:translate3d(-25%,0,0) rotate(-5deg);transform:translate3d(-25%,0,0) rotate(-5deg)}30%{-webkit-transform:translate3d(20%,0,0) rotate(3deg);transform:translate3d(20%,0,0) rotate(3deg)}45%{-webkit-transform:translate3d(-15%,0,0) rotate(-3deg);transform:translate3d(-15%,0,0) rotate(-3deg)}60%{-webkit-transform:translate3d(10%,0,0) rotate(2deg);transform:translate3d(10%,0,0) rotate(2deg)}75%{-webkit-transform:translate3d(-5%,0,0) rotate(-1deg);transform:translate3d(-5%,0,0) rotate(-1deg)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes wobble{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}15%{-webkit-transform:translate3d(-25%,0,0) rotate(-5deg);transform:translate3d(-25%,0,0) rotate(-5deg)}30%{-webkit-transform:translate3d(20%,0,0) rotate(3deg);transform:translate3d(20%,0,0) rotate(3deg)}45%{-webkit-transform:translate3d(-15%,0,0) rotate(-3deg);transform:translate3d(-15%,0,0) rotate(-3deg)}60%{-webkit-transform:translate3d(10%,0,0) rotate(2deg);transform:translate3d(10%,0,0) rotate(2deg)}75%{-webkit-transform:translate3d(-5%,0,0) rotate(-1deg);transform:translate3d(-5%,0,0) rotate(-1deg)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.wobble{-webkit-animation-name:wobble;animation-name:wobble}@-webkit-keyframes jello{0%,11.1%,to{-webkit-transform:translateZ(0);transform:translateZ(0)}22.2%{-webkit-transform:skewX(-12.5deg) skewY(-12.5deg);transform:skewX(-12.5deg) skewY(-12.5deg)}33.3%{-webkit-transform:skewX(6.25deg) skewY(6.25deg);transform:skewX(6.25deg) skewY(6.25deg)}44.4%{-webkit-transform:skewX(-3.125deg) skewY(-3.125deg);transform:skewX(-3.125deg) skewY(-3.125deg)}55.5%{-webkit-transform:skewX(1.5625deg) skewY(1.5625deg);transform:skewX(1.5625deg) skewY(1.5625deg)}66.6%{-webkit-transform:skewX(-.78125deg) skewY(-.78125deg);transform:skewX(-.78125deg) skewY(-.78125deg)}77.7%{-webkit-transform:skewX(.390625deg) skewY(.390625deg);transform:skewX(.390625deg) skewY(.390625deg)}88.8%{-webkit-transform:skewX(-.1953125deg) skewY(-.1953125deg);transform:skewX(-.1953125deg) skewY(-.1953125deg)}}@keyframes jello{0%,11.1%,to{-webkit-transform:translateZ(0);transform:translateZ(0)}22.2%{-webkit-transform:skewX(-12.5deg) skewY(-12.5deg);transform:skewX(-12.5deg) skewY(-12.5deg)}33.3%{-webkit-transform:skewX(6.25deg) skewY(6.25deg);transform:skewX(6.25deg) skewY(6.25deg)}44.4%{-webkit-transform:skewX(-3.125deg) skewY(-3.125deg);transform:skewX(-3.125deg) skewY(-3.125deg)}55.5%{-webkit-transform:skewX(1.5625deg) skewY(1.5625deg);transform:skewX(1.5625deg) skewY(1.5625deg)}66.6%{-webkit-transform:skewX(-.78125deg) skewY(-.78125deg);transform:skewX(-.78125deg) skewY(-.78125deg)}77.7%{-webkit-transform:skewX(.390625deg) skewY(.390625deg);transform:skewX(.390625deg) skewY(.390625deg)}88.8%{-webkit-transform:skewX(-.1953125deg) skewY(-.1953125deg);transform:skewX(-.1953125deg) skewY(-.1953125deg)}}.jello{-webkit-animation-name:jello;animation-name:jello;-webkit-transform-origin:center;transform-origin:center}@-webkit-keyframes bounceIn{0%,20%,40%,60%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}20%{-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}40%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}60%{opacity:1;-webkit-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}80%{-webkit-transform:scale3d(.97,.97,.97);transform:scale3d(.97,.97,.97)}to{opacity:1;-webkit-transform:scaleX(1);transform:scaleX(1)}}@keyframes bounceIn{0%,20%,40%,60%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}20%{-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}40%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}60%{opacity:1;-webkit-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}80%{-webkit-transform:scale3d(.97,.97,.97);transform:scale3d(.97,.97,.97)}to{opacity:1;-webkit-transform:scaleX(1);transform:scaleX(1)}}.bounceIn{-webkit-animation-duration:.75s;animation-duration:.75s;-webkit-animation-name:bounceIn;animation-name:bounceIn}@-webkit-keyframes bounceInDown{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,-3000px,0);transform:translate3d(0,-3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,25px,0);transform:translate3d(0,25px,0)}75%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}90%{-webkit-transform:translate3d(0,5px,0);transform:translate3d(0,5px,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes bounceInDown{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,-3000px,0);transform:translate3d(0,-3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,25px,0);transform:translate3d(0,25px,0)}75%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}90%{-webkit-transform:translate3d(0,5px,0);transform:translate3d(0,5px,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.bounceInDown{-webkit-animation-name:bounceInDown;animation-name:bounceInDown}@-webkit-keyframes bounceInLeft{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(-3000px,0,0);transform:translate3d(-3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(25px,0,0);transform:translate3d(25px,0,0)}75%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}90%{-webkit-transform:translate3d(5px,0,0);transform:translate3d(5px,0,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes bounceInLeft{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(-3000px,0,0);transform:translate3d(-3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(25px,0,0);transform:translate3d(25px,0,0)}75%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}90%{-webkit-transform:translate3d(5px,0,0);transform:translate3d(5px,0,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.bounceInLeft{-webkit-animation-name:bounceInLeft;animation-name:bounceInLeft}@-webkit-keyframes bounceInRight{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(3000px,0,0);transform:translate3d(3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0);transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes bounceInRight{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(3000px,0,0);transform:translate3d(3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0);transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.bounceInRight{-webkit-animation-name:bounceInRight;animation-name:bounceInRight}@-webkit-keyframes bounceInUp{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,3000px,0);transform:translate3d(0,3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}75%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}90%{-webkit-transform:translate3d(0,-5px,0);transform:translate3d(0,-5px,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes bounceInUp{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,3000px,0);transform:translate3d(0,3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}75%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}90%{-webkit-transform:translate3d(0,-5px,0);transform:translate3d(0,-5px,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.bounceInUp{-webkit-animation-name:bounceInUp;animation-name:bounceInUp}@-webkit-keyframes bounceOut{20%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}50%,55%{opacity:1;-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}to{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}}@keyframes bounceOut{20%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}50%,55%{opacity:1;-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}to{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}}.bounceOut{-webkit-animation-duration:.75s;animation-duration:.75s;-webkit-animation-name:bounceOut;animation-name:bounceOut}@-webkit-keyframes bounceOutDown{20%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}to{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}@keyframes bounceOutDown{20%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}to{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}.bounceOutDown{-webkit-animation-name:bounceOutDown;animation-name:bounceOutDown}@-webkit-keyframes bounceOutLeft{20%{opacity:1;-webkit-transform:translate3d(20px,0,0);transform:translate3d(20px,0,0)}to{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}@keyframes bounceOutLeft{20%{opacity:1;-webkit-transform:translate3d(20px,0,0);transform:translate3d(20px,0,0)}to{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}.bounceOutLeft{-webkit-animation-name:bounceOutLeft;animation-name:bounceOutLeft}@-webkit-keyframes bounceOutRight{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}to{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}@keyframes bounceOutRight{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}to{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}.bounceOutRight{-webkit-animation-name:bounceOutRight;animation-name:bounceOutRight}@-webkit-keyframes bounceOutUp{20%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,20px,0);transform:translate3d(0,20px,0)}to{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}@keyframes bounceOutUp{20%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,20px,0);transform:translate3d(0,20px,0)}to{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}.bounceOutUp{-webkit-animation-name:bounceOutUp;animation-name:bounceOutUp}@-webkit-keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.fadeIn{-webkit-animation-name:fadeIn;animation-name:fadeIn}@-webkit-keyframes fadeInDown{0%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes fadeInDown{0%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}.fadeInDown{-webkit-animation-name:fadeInDown;animation-name:fadeInDown}@-webkit-keyframes fadeInDownBig{0%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes fadeInDownBig{0%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}.fadeInDownBig{-webkit-animation-name:fadeInDownBig;animation-name:fadeInDownBig}@-webkit-keyframes fadeInLeft{0%{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes fadeInLeft{0%{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}.fadeInLeft{-webkit-animation-name:fadeInLeft;animation-name:fadeInLeft}@-webkit-keyframes fadeInLeftBig{0%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes fadeInLeftBig{0%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}.fadeInLeftBig{-webkit-animation-name:fadeInLeftBig;animation-name:fadeInLeftBig}@-webkit-keyframes fadeInRight{0%{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes fadeInRight{0%{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}.fadeInRight{-webkit-animation-name:fadeInRight;animation-name:fadeInRight}@-webkit-keyframes fadeInRightBig{0%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes fadeInRightBig{0%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}.fadeInRightBig{-webkit-animation-name:fadeInRightBig;animation-name:fadeInRightBig}@-webkit-keyframes fadeInUp{0%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes fadeInUp{0%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}.fadeInUp{-webkit-animation-name:fadeInUp;animation-name:fadeInUp}@-webkit-keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}.fadeInUpBig{-webkit-animation-name:fadeInUpBig;animation-name:fadeInUpBig}@-webkit-keyframes fadeOut{0%{opacity:1}to{opacity:0}}@keyframes fadeOut{0%{opacity:1}to{opacity:0}}.fadeOut{-webkit-animation-name:fadeOut;animation-name:fadeOut}@-webkit-keyframes fadeOutDown{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@keyframes fadeOutDown{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}.fadeOutDown{-webkit-animation-name:fadeOutDown;animation-name:fadeOutDown}@-webkit-keyframes fadeOutDownBig{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}@keyframes fadeOutDownBig{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}.fadeOutDownBig{-webkit-animation-name:fadeOutDownBig;animation-name:fadeOutDownBig}@-webkit-keyframes fadeOutLeft{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@keyframes fadeOutLeft{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.fadeOutLeft{-webkit-animation-name:fadeOutLeft;animation-name:fadeOutLeft}@-webkit-keyframes fadeOutLeftBig{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}@keyframes fadeOutLeftBig{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}.fadeOutLeftBig{-webkit-animation-name:fadeOutLeftBig;animation-name:fadeOutLeftBig}@-webkit-keyframes fadeOutRight{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@keyframes fadeOutRight{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.fadeOutRight{-webkit-animation-name:fadeOutRight;animation-name:fadeOutRight}@-webkit-keyframes fadeOutRightBig{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}@keyframes fadeOutRightBig{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}.fadeOutRightBig{-webkit-animation-name:fadeOutRightBig;animation-name:fadeOutRightBig}@-webkit-keyframes fadeOutUp{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@keyframes fadeOutUp{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}.fadeOutUp{-webkit-animation-name:fadeOutUp;animation-name:fadeOutUp}@-webkit-keyframes fadeOutUpBig{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}@keyframes fadeOutUpBig{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}.fadeOutUpBig{-webkit-animation-name:fadeOutUpBig;animation-name:fadeOutUpBig}@-webkit-keyframes flip{0%{-webkit-transform:perspective(400px) rotateY(-1turn);transform:perspective(400px) rotateY(-1turn);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}40%{-webkit-transform:perspective(400px) translateZ(150px) rotateY(-190deg);transform:perspective(400px) translateZ(150px) rotateY(-190deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}50%{-webkit-transform:perspective(400px) translateZ(150px) rotateY(-170deg);transform:perspective(400px) translateZ(150px) rotateY(-170deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}80%{-webkit-transform:perspective(400px) scale3d(.95,.95,.95);transform:perspective(400px) scale3d(.95,.95,.95);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}to{-webkit-transform:perspective(400px);transform:perspective(400px);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}}@keyframes flip{0%{-webkit-transform:perspective(400px) rotateY(-1turn);transform:perspective(400px) rotateY(-1turn);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}40%{-webkit-transform:perspective(400px) translateZ(150px) rotateY(-190deg);transform:perspective(400px) translateZ(150px) rotateY(-190deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}50%{-webkit-transform:perspective(400px) translateZ(150px) rotateY(-170deg);transform:perspective(400px) translateZ(150px) rotateY(-170deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}80%{-webkit-transform:perspective(400px) scale3d(.95,.95,.95);transform:perspective(400px) scale3d(.95,.95,.95);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}to{-webkit-transform:perspective(400px);transform:perspective(400px);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}}.animated.flip{-webkit-backface-visibility:visible;backface-visibility:visible;-webkit-animation-name:flip;animation-name:flip}@-webkit-keyframes flipInX{0%{-webkit-transform:perspective(400px) rotateX(90deg);transform:perspective(400px) rotateX(90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotateX(-20deg);transform:perspective(400px) rotateX(-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotateX(10deg);transform:perspective(400px) rotateX(10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotateX(-5deg);transform:perspective(400px) rotateX(-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}@keyframes flipInX{0%{-webkit-transform:perspective(400px) rotateX(90deg);transform:perspective(400px) rotateX(90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotateX(-20deg);transform:perspective(400px) rotateX(-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotateX(10deg);transform:perspective(400px) rotateX(10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotateX(-5deg);transform:perspective(400px) rotateX(-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}.flipInX{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipInX;animation-name:flipInX}@-webkit-keyframes flipInY{0%{-webkit-transform:perspective(400px) rotateY(90deg);transform:perspective(400px) rotateY(90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotateY(-20deg);transform:perspective(400px) rotateY(-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotateY(10deg);transform:perspective(400px) rotateY(10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotateY(-5deg);transform:perspective(400px) rotateY(-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}@keyframes flipInY{0%{-webkit-transform:perspective(400px) rotateY(90deg);transform:perspective(400px) rotateY(90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotateY(-20deg);transform:perspective(400px) rotateY(-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotateY(10deg);transform:perspective(400px) rotateY(10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotateY(-5deg);transform:perspective(400px) rotateY(-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}.flipInY{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipInY;animation-name:flipInY}@-webkit-keyframes flipOutX{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotateX(-20deg);transform:perspective(400px) rotateX(-20deg);opacity:1}to{-webkit-transform:perspective(400px) rotateX(90deg);transform:perspective(400px) rotateX(90deg);opacity:0}}@keyframes flipOutX{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotateX(-20deg);transform:perspective(400px) rotateX(-20deg);opacity:1}to{-webkit-transform:perspective(400px) rotateX(90deg);transform:perspective(400px) rotateX(90deg);opacity:0}}.flipOutX{-webkit-animation-duration:.75s;animation-duration:.75s;-webkit-animation-name:flipOutX;animation-name:flipOutX;-webkit-backface-visibility:visible!important;backface-visibility:visible!important}@-webkit-keyframes flipOutY{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotateY(-15deg);transform:perspective(400px) rotateY(-15deg);opacity:1}to{-webkit-transform:perspective(400px) rotateY(90deg);transform:perspective(400px) rotateY(90deg);opacity:0}}@keyframes flipOutY{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotateY(-15deg);transform:perspective(400px) rotateY(-15deg);opacity:1}to{-webkit-transform:perspective(400px) rotateY(90deg);transform:perspective(400px) rotateY(90deg);opacity:0}}.flipOutY{-webkit-animation-duration:.75s;animation-duration:.75s;-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipOutY;animation-name:flipOutY}@-webkit-keyframes lightSpeedIn{0%{-webkit-transform:translate3d(100%,0,0) skewX(-30deg);transform:translate3d(100%,0,0) skewX(-30deg);opacity:0}60%{-webkit-transform:skewX(20deg);transform:skewX(20deg);opacity:1}80%{-webkit-transform:skewX(-5deg);transform:skewX(-5deg);opacity:1}to{-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}}@keyframes lightSpeedIn{0%{-webkit-transform:translate3d(100%,0,0) skewX(-30deg);transform:translate3d(100%,0,0) skewX(-30deg);opacity:0}60%{-webkit-transform:skewX(20deg);transform:skewX(20deg);opacity:1}80%{-webkit-transform:skewX(-5deg);transform:skewX(-5deg);opacity:1}to{-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}}.lightSpeedIn{-webkit-animation-name:lightSpeedIn;animation-name:lightSpeedIn;-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}@-webkit-keyframes lightSpeedOut{0%{opacity:1}to{-webkit-transform:translate3d(100%,0,0) skewX(30deg);transform:translate3d(100%,0,0) skewX(30deg);opacity:0}}@keyframes lightSpeedOut{0%{opacity:1}to{-webkit-transform:translate3d(100%,0,0) skewX(30deg);transform:translate3d(100%,0,0) skewX(30deg);opacity:0}}.lightSpeedOut{-webkit-animation-name:lightSpeedOut;animation-name:lightSpeedOut;-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}@-webkit-keyframes rotateIn{0%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate(-200deg);transform:rotate(-200deg);opacity:0}to{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}}@keyframes rotateIn{0%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate(-200deg);transform:rotate(-200deg);opacity:0}to{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}}.rotateIn{-webkit-animation-name:rotateIn;animation-name:rotateIn}@-webkit-keyframes rotateInDownLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);opacity:0}to{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}}@keyframes rotateInDownLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);opacity:0}to{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}}.rotateInDownLeft{-webkit-animation-name:rotateInDownLeft;animation-name:rotateInDownLeft}@-webkit-keyframes rotateInDownRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate(45deg);transform:rotate(45deg);opacity:0}to{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}}@keyframes rotateInDownRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate(45deg);transform:rotate(45deg);opacity:0}to{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}}.rotateInDownRight{-webkit-animation-name:rotateInDownRight;animation-name:rotateInDownRight}@-webkit-keyframes rotateInUpLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate(45deg);transform:rotate(45deg);opacity:0}to{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}}@keyframes rotateInUpLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate(45deg);transform:rotate(45deg);opacity:0}to{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}}.rotateInUpLeft{-webkit-animation-name:rotateInUpLeft;animation-name:rotateInUpLeft}@-webkit-keyframes rotateInUpRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate(-90deg);transform:rotate(-90deg);opacity:0}to{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}}@keyframes rotateInUpRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate(-90deg);transform:rotate(-90deg);opacity:0}to{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}}.rotateInUpRight{-webkit-animation-name:rotateInUpRight;animation-name:rotateInUpRight}@-webkit-keyframes rotateOut{0%{-webkit-transform-origin:center;transform-origin:center;opacity:1}to{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate(200deg);transform:rotate(200deg);opacity:0}}@keyframes rotateOut{0%{-webkit-transform-origin:center;transform-origin:center;opacity:1}to{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate(200deg);transform:rotate(200deg);opacity:0}}.rotateOut{-webkit-animation-name:rotateOut;animation-name:rotateOut}@-webkit-keyframes rotateOutDownLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}to{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate(45deg);transform:rotate(45deg);opacity:0}}@keyframes rotateOutDownLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}to{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate(45deg);transform:rotate(45deg);opacity:0}}.rotateOutDownLeft{-webkit-animation-name:rotateOutDownLeft;animation-name:rotateOutDownLeft}@-webkit-keyframes rotateOutDownRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}to{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);opacity:0}}@keyframes rotateOutDownRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}to{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);opacity:0}}.rotateOutDownRight{-webkit-animation-name:rotateOutDownRight;animation-name:rotateOutDownRight}@-webkit-keyframes rotateOutUpLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}to{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);opacity:0}}@keyframes rotateOutUpLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}to{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);opacity:0}}.rotateOutUpLeft{-webkit-animation-name:rotateOutUpLeft;animation-name:rotateOutUpLeft}@-webkit-keyframes rotateOutUpRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}to{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate(90deg);transform:rotate(90deg);opacity:0}}@keyframes rotateOutUpRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}to{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate(90deg);transform:rotate(90deg);opacity:0}}.rotateOutUpRight{-webkit-animation-name:rotateOutUpRight;animation-name:rotateOutUpRight}@-webkit-keyframes hinge{0%{-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}20%,60%{-webkit-transform:rotate(80deg);transform:rotate(80deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}40%,80%{-webkit-transform:rotate(60deg);transform:rotate(60deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;opacity:1}to{-webkit-transform:translate3d(0,700px,0);transform:translate3d(0,700px,0);opacity:0}}@keyframes hinge{0%{-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}20%,60%{-webkit-transform:rotate(80deg);transform:rotate(80deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}40%,80%{-webkit-transform:rotate(60deg);transform:rotate(60deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;opacity:1}to{-webkit-transform:translate3d(0,700px,0);transform:translate3d(0,700px,0);opacity:0}}.hinge{-webkit-animation-duration:2s;animation-duration:2s;-webkit-animation-name:hinge;animation-name:hinge}@-webkit-keyframes jackInTheBox{0%{opacity:0;-webkit-transform:scale(.1) rotate(30deg);transform:scale(.1) rotate(30deg);-webkit-transform-origin:center bottom;transform-origin:center bottom}50%{-webkit-transform:rotate(-10deg);transform:rotate(-10deg)}70%{-webkit-transform:rotate(3deg);transform:rotate(3deg)}to{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}@keyframes jackInTheBox{0%{opacity:0;-webkit-transform:scale(.1) rotate(30deg);transform:scale(.1) rotate(30deg);-webkit-transform-origin:center bottom;transform-origin:center bottom}50%{-webkit-transform:rotate(-10deg);transform:rotate(-10deg)}70%{-webkit-transform:rotate(3deg);transform:rotate(3deg)}to{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}.jackInTheBox{-webkit-animation-name:jackInTheBox;animation-name:jackInTheBox}@-webkit-keyframes rollIn{0%{opacity:0;-webkit-transform:translate3d(-100%,0,0) rotate(-120deg);transform:translate3d(-100%,0,0) rotate(-120deg)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes rollIn{0%{opacity:0;-webkit-transform:translate3d(-100%,0,0) rotate(-120deg);transform:translate3d(-100%,0,0) rotate(-120deg)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}.rollIn{-webkit-animation-name:rollIn;animation-name:rollIn}@-webkit-keyframes rollOut{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(100%,0,0) rotate(120deg);transform:translate3d(100%,0,0) rotate(120deg)}}@keyframes rollOut{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(100%,0,0) rotate(120deg);transform:translate3d(100%,0,0) rotate(120deg)}}.rollOut{-webkit-animation-name:rollOut;animation-name:rollOut}@-webkit-keyframes zoomIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}@keyframes zoomIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}.zoomIn{-webkit-animation-name:zoomIn;animation-name:zoomIn}@-webkit-keyframes zoomInDown{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}@keyframes zoomInDown{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}.zoomInDown{-webkit-animation-name:zoomInDown;animation-name:zoomInDown}@-webkit-keyframes zoomInLeft{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(10px,0,0);transform:scale3d(.475,.475,.475) translate3d(10px,0,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}@keyframes zoomInLeft{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(10px,0,0);transform:scale3d(.475,.475,.475) translate3d(10px,0,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}.zoomInLeft{-webkit-animation-name:zoomInLeft;animation-name:zoomInLeft}@-webkit-keyframes zoomInRight{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}@keyframes zoomInRight{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}.zoomInRight{-webkit-animation-name:zoomInRight;animation-name:zoomInRight}@-webkit-keyframes zoomInUp{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}@keyframes zoomInUp{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}.zoomInUp{-webkit-animation-name:zoomInUp;animation-name:zoomInUp}@-webkit-keyframes zoomOut{0%{opacity:1}50%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}to{opacity:0}}@keyframes zoomOut{0%{opacity:1}50%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}to{opacity:0}}.zoomOut{-webkit-animation-name:zoomOut;animation-name:zoomOut}@-webkit-keyframes zoomOutDown{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}to{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}@keyframes zoomOutDown{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}to{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}.zoomOutDown{-webkit-animation-name:zoomOutDown;animation-name:zoomOutDown}@-webkit-keyframes zoomOutLeft{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(42px,0,0);transform:scale3d(.475,.475,.475) translate3d(42px,0,0)}to{opacity:0;-webkit-transform:scale(.1) translate3d(-2000px,0,0);transform:scale(.1) translate3d(-2000px,0,0);-webkit-transform-origin:left center;transform-origin:left center}}@keyframes zoomOutLeft{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(42px,0,0);transform:scale3d(.475,.475,.475) translate3d(42px,0,0)}to{opacity:0;-webkit-transform:scale(.1) translate3d(-2000px,0,0);transform:scale(.1) translate3d(-2000px,0,0);-webkit-transform-origin:left center;transform-origin:left center}}.zoomOutLeft{-webkit-animation-name:zoomOutLeft;animation-name:zoomOutLeft}@-webkit-keyframes zoomOutRight{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-42px,0,0);transform:scale3d(.475,.475,.475) translate3d(-42px,0,0)}to{opacity:0;-webkit-transform:scale(.1) translate3d(2000px,0,0);transform:scale(.1) translate3d(2000px,0,0);-webkit-transform-origin:right center;transform-origin:right center}}@keyframes zoomOutRight{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-42px,0,0);transform:scale3d(.475,.475,.475) translate3d(-42px,0,0)}to{opacity:0;-webkit-transform:scale(.1) translate3d(2000px,0,0);transform:scale(.1) translate3d(2000px,0,0);-webkit-transform-origin:right center;transform-origin:right center}}.zoomOutRight{-webkit-animation-name:zoomOutRight;animation-name:zoomOutRight}@-webkit-keyframes zoomOutUp{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}to{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}@keyframes zoomOutUp{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}to{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}.zoomOutUp{-webkit-animation-name:zoomOutUp;animation-name:zoomOutUp}@-webkit-keyframes slideInDown{0%{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes slideInDown{0%{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.slideInDown{-webkit-animation-name:slideInDown;animation-name:slideInDown}@-webkit-keyframes slideInLeft{0%{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes slideInLeft{0%{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.slideInLeft{-webkit-animation-name:slideInLeft;animation-name:slideInLeft}@-webkit-keyframes slideInRight{0%{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes slideInRight{0%{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.slideInRight{-webkit-animation-name:slideInRight;animation-name:slideInRight}@-webkit-keyframes slideInUp{0%{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes slideInUp{0%{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.slideInUp{-webkit-animation-name:slideInUp;animation-name:slideInUp}@-webkit-keyframes slideOutDown{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@keyframes slideOutDown{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}.slideOutDown{-webkit-animation-name:slideOutDown;animation-name:slideOutDown}@-webkit-keyframes slideOutLeft{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@keyframes slideOutLeft{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.slideOutLeft{-webkit-animation-name:slideOutLeft;animation-name:slideOutLeft}@-webkit-keyframes slideOutRight{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@keyframes slideOutRight{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.slideOutRight{-webkit-animation-name:slideOutRight;animation-name:slideOutRight}@-webkit-keyframes slideOutUp{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@keyframes slideOutUp{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}.slideOutUp{-webkit-animation-name:slideOutUp;animation-name:slideOutUp}
includes/feedback/assets/css/emoji.css ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*shows the stars side by side, centered, and in reverse order than the HMTL*/
2
+ .emoji {
3
+ display: flex;
4
+ flex-direction: row-reverse;
5
+ justify-content: center;
6
+ }
7
+
8
+ /*hides the radio buttons*/
9
+ .emoji > input {
10
+ display: none;
11
+ }
12
+
13
+
14
+
15
+ /*style the empty stars, sets position:relative as base for pseudo-elements*/
16
+ .emoji > label {
17
+ position: relative;
18
+ width: 1.1em;
19
+ font-size: 2em;
20
+ color: #FFD700;
21
+ cursor: pointer;
22
+ }
23
+
24
+ /*overlays a filled start character on the selected element and all previous siblings*/
25
+ .ig-emoji.active {
26
+ border: 1px solid black;
27
+ }
28
+
29
+ #emoji-info {
30
+ font-size: 14px;
31
+ height: 15px;
32
+ }
33
+
34
+ @media only screen and (max-width: 600px) {
35
+ h1 {
36
+ font-size: 14px;
37
+ }
38
+
39
+ p {
40
+ font-size: 12px;
41
+ }
42
+ }
includes/feedback/assets/css/star-rating.css ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*shows the stars side by side, centered, and in reverse order than the HMTL*/
2
+ .rating {
3
+ display: flex;
4
+ flex-direction: row-reverse;
5
+ justify-content: center;
6
+ }
7
+
8
+ /*hides the radio buttons*/
9
+ .rating > input{ display:none;}
10
+
11
+ /*style the empty stars, sets position:relative as base for pseudo-elements*/
12
+ .rating > label {
13
+ position: relative;
14
+ width: 1.1em;
15
+ font-size: 2em;
16
+ color: #FFD700;
17
+ cursor: pointer;
18
+ }
19
+
20
+ /* sets filled star pseudo-elements */
21
+ .rating > label::before{
22
+ content: "\2605";
23
+ position: absolute;
24
+ opacity: 0;
25
+ }
26
+ /*overlays a filled start character to the hovered element and all previous siblings*/
27
+ .rating > label:hover:before,
28
+ .rating > label:hover ~ label:before {
29
+ opacity: 1 !important;
30
+ }
31
+
32
+ /*overlays a filled start character on the selected element and all previous siblings*/
33
+ .rating > input:checked ~ label:before{
34
+ opacity:1;
35
+ }
36
+
37
+ /*when an element is selected and pointer re-enters the rating container, selected rate and siblings get semi transparent, as reminder of current selection*/
38
+ .rating:hover > input:checked ~ label:before{ opacity: 0.4; }
39
+
40
+ .rating > input[type=radio]:checked+label:before {
41
+ color: #FFD700;
42
+ }
43
+
44
+ .ig-feedback-title {
45
+ font-size: 20px;
46
+ line-height: 1.5em;
47
+ margin: 0em 0;
48
+ }
49
+ @media only screen and (max-width: 600px) {
50
+ h1{font-size: 14px;}
51
+ p{font-size: 12px;}
52
+ }
includes/feedback/assets/css/sweetalert2.css ADDED
@@ -0,0 +1,1453 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @charset "UTF-8";
2
+ @-webkit-keyframes swal2-show {
3
+ 0% {
4
+ -webkit-transform: scale(0.7);
5
+ transform: scale(0.7);
6
+ }
7
+ 45% {
8
+ -webkit-transform: scale(1.05);
9
+ transform: scale(1.05);
10
+ }
11
+ 80% {
12
+ -webkit-transform: scale(0.95);
13
+ transform: scale(0.95);
14
+ }
15
+ 100% {
16
+ -webkit-transform: scale(1);
17
+ transform: scale(1);
18
+ }
19
+ }
20
+ @keyframes swal2-show {
21
+ 0% {
22
+ -webkit-transform: scale(0.7);
23
+ transform: scale(0.7);
24
+ }
25
+ 45% {
26
+ -webkit-transform: scale(1.05);
27
+ transform: scale(1.05);
28
+ }
29
+ 80% {
30
+ -webkit-transform: scale(0.95);
31
+ transform: scale(0.95);
32
+ }
33
+ 100% {
34
+ -webkit-transform: scale(1);
35
+ transform: scale(1);
36
+ }
37
+ }
38
+ @-webkit-keyframes swal2-hide {
39
+ 0% {
40
+ -webkit-transform: scale(1);
41
+ transform: scale(1);
42
+ opacity: 1;
43
+ }
44
+ 100% {
45
+ -webkit-transform: scale(0.5);
46
+ transform: scale(0.5);
47
+ opacity: 0;
48
+ }
49
+ }
50
+ @keyframes swal2-hide {
51
+ 0% {
52
+ -webkit-transform: scale(1);
53
+ transform: scale(1);
54
+ opacity: 1;
55
+ }
56
+ 100% {
57
+ -webkit-transform: scale(0.5);
58
+ transform: scale(0.5);
59
+ opacity: 0;
60
+ }
61
+ }
62
+ @-webkit-keyframes swal2-animate-success-line-tip {
63
+ 0% {
64
+ top: 1.1875em;
65
+ left: 0.0625em;
66
+ width: 0;
67
+ }
68
+ 54% {
69
+ top: 1.0625em;
70
+ left: 0.125em;
71
+ width: 0;
72
+ }
73
+ 70% {
74
+ top: 2.1875em;
75
+ left: -0.375em;
76
+ width: 3.125em;
77
+ }
78
+ 84% {
79
+ top: 3em;
80
+ left: 1.3125em;
81
+ width: 1.0625em;
82
+ }
83
+ 100% {
84
+ top: 2.8125em;
85
+ left: 0.875em;
86
+ width: 1.5625em;
87
+ }
88
+ }
89
+ @keyframes swal2-animate-success-line-tip {
90
+ 0% {
91
+ top: 1.1875em;
92
+ left: 0.0625em;
93
+ width: 0;
94
+ }
95
+ 54% {
96
+ top: 1.0625em;
97
+ left: 0.125em;
98
+ width: 0;
99
+ }
100
+ 70% {
101
+ top: 2.1875em;
102
+ left: -0.375em;
103
+ width: 3.125em;
104
+ }
105
+ 84% {
106
+ top: 3em;
107
+ left: 1.3125em;
108
+ width: 1.0625em;
109
+ }
110
+ 100% {
111
+ top: 2.8125em;
112
+ left: 0.875em;
113
+ width: 1.5625em;
114
+ }
115
+ }
116
+ @-webkit-keyframes swal2-animate-success-line-long {
117
+ 0% {
118
+ top: 3.375em;
119
+ right: 2.875em;
120
+ width: 0;
121
+ }
122
+ 65% {
123
+ top: 3.375em;
124
+ right: 2.875em;
125
+ width: 0;
126
+ }
127
+ 84% {
128
+ top: 2.1875em;
129
+ right: 0;
130
+ width: 3.4375em;
131
+ }
132
+ 100% {
133
+ top: 2.375em;
134
+ right: 0.5em;
135
+ width: 2.9375em;
136
+ }
137
+ }
138
+ @keyframes swal2-animate-success-line-long {
139
+ 0% {
140
+ top: 3.375em;
141
+ right: 2.875em;
142
+ width: 0;
143
+ }
144
+ 65% {
145
+ top: 3.375em;
146
+ right: 2.875em;
147
+ width: 0;
148
+ }
149
+ 84% {
150
+ top: 2.1875em;
151
+ right: 0;
152
+ width: 3.4375em;
153
+ }
154
+ 100% {
155
+ top: 2.375em;
156
+ right: 0.5em;
157
+ width: 2.9375em;
158
+ }
159
+ }
160
+ @-webkit-keyframes swal2-rotate-success-circular-line {
161
+ 0% {
162
+ -webkit-transform: rotate(-45deg);
163
+ transform: rotate(-45deg);
164
+ }
165
+ 5% {
166
+ -webkit-transform: rotate(-45deg);
167
+ transform: rotate(-45deg);
168
+ }
169
+ 12% {
170
+ -webkit-transform: rotate(-405deg);
171
+ transform: rotate(-405deg);
172
+ }
173
+ 100% {
174
+ -webkit-transform: rotate(-405deg);
175
+ transform: rotate(-405deg);
176
+ }
177
+ }
178
+ @keyframes swal2-rotate-success-circular-line {
179
+ 0% {
180
+ -webkit-transform: rotate(-45deg);
181
+ transform: rotate(-45deg);
182
+ }
183
+ 5% {
184
+ -webkit-transform: rotate(-45deg);
185
+ transform: rotate(-45deg);
186
+ }
187
+ 12% {
188
+ -webkit-transform: rotate(-405deg);
189
+ transform: rotate(-405deg);
190
+ }
191
+ 100% {
192
+ -webkit-transform: rotate(-405deg);
193
+ transform: rotate(-405deg);
194
+ }
195
+ }
196
+ @-webkit-keyframes swal2-animate-error-x-mark {
197
+ 0% {
198
+ margin-top: 1.625em;
199
+ -webkit-transform: scale(0.4);
200
+ transform: scale(0.4);
201
+ opacity: 0;
202
+ }
203
+ 50% {
204
+ margin-top: 1.625em;
205
+ -webkit-transform: scale(0.4);
206
+ transform: scale(0.4);
207
+ opacity: 0;
208
+ }
209
+ 80% {
210
+ margin-top: -0.375em;
211
+ -webkit-transform: scale(1.15);
212
+ transform: scale(1.15);
213
+ }
214
+ 100% {
215
+ margin-top: 0;
216
+ -webkit-transform: scale(1);
217
+ transform: scale(1);
218
+ opacity: 1;
219
+ }
220
+ }
221
+ @keyframes swal2-animate-error-x-mark {
222
+ 0% {
223
+ margin-top: 1.625em;
224
+ -webkit-transform: scale(0.4);
225
+ transform: scale(0.4);
226
+ opacity: 0;
227
+ }
228
+ 50% {
229
+ margin-top: 1.625em;
230
+ -webkit-transform: scale(0.4);
231
+ transform: scale(0.4);
232
+ opacity: 0;
233
+ }
234
+ 80% {
235
+ margin-top: -0.375em;
236
+ -webkit-transform: scale(1.15);
237
+ transform: scale(1.15);
238
+ }
239
+ 100% {
240
+ margin-top: 0;
241
+ -webkit-transform: scale(1);
242
+ transform: scale(1);
243
+ opacity: 1;
244
+ }
245
+ }
246
+ @-webkit-keyframes swal2-animate-error-icon {
247
+ 0% {
248
+ -webkit-transform: rotateX(100deg);
249
+ transform: rotateX(100deg);
250
+ opacity: 0;
251
+ }
252
+ 100% {
253
+ -webkit-transform: rotateX(0deg);
254
+ transform: rotateX(0deg);
255
+ opacity: 1;
256
+ }
257
+ }
258
+ @keyframes swal2-animate-error-icon {
259
+ 0% {
260
+ -webkit-transform: rotateX(100deg);
261
+ transform: rotateX(100deg);
262
+ opacity: 0;
263
+ }
264
+ 100% {
265
+ -webkit-transform: rotateX(0deg);
266
+ transform: rotateX(0deg);
267
+ opacity: 1;
268
+ }
269
+ }
270
+ body.swal2-toast-shown .swal2-container {
271
+ background-color: transparent;
272
+ }
273
+ body.swal2-toast-shown .swal2-container.swal2-shown {
274
+ background-color: transparent;
275
+ }
276
+ body.swal2-toast-shown .swal2-container.swal2-top {
277
+ top: 0;
278
+ right: auto;
279
+ bottom: auto;
280
+ left: 50%;
281
+ -webkit-transform: translateX(-50%);
282
+ transform: translateX(-50%);
283
+ }
284
+ body.swal2-toast-shown .swal2-container.swal2-top-end, body.swal2-toast-shown .swal2-container.swal2-top-right {
285
+ top: 0;
286
+ right: 0;
287
+ bottom: auto;
288
+ left: auto;
289
+ }
290
+ body.swal2-toast-shown .swal2-container.swal2-top-start, body.swal2-toast-shown .swal2-container.swal2-top-left {
291
+ top: 0;
292
+ right: auto;
293
+ bottom: auto;
294
+ left: 0;
295
+ }
296
+ body.swal2-toast-shown .swal2-container.swal2-center-start, body.swal2-toast-shown .swal2-container.swal2-center-left {
297
+ top: 50%;
298
+ right: auto;
299
+ bottom: auto;
300
+ left: 0;
301
+ -webkit-transform: translateY(-50%);
302
+ transform: translateY(-50%);
303
+ }
304
+ body.swal2-toast-shown .swal2-container.swal2-center {
305
+ top: 50%;
306
+ right: auto;
307
+ bottom: auto;
308
+ left: 50%;
309
+ -webkit-transform: translate(-50%, -50%);
310
+ transform: translate(-50%, -50%);
311
+ }
312
+ body.swal2-toast-shown .swal2-container.swal2-center-end, body.swal2-toast-shown .swal2-container.swal2-center-right {
313
+ top: 50%;
314
+ right: 0;
315
+ bottom: auto;
316
+ left: auto;
317
+ -webkit-transform: translateY(-50%);
318
+ transform: translateY(-50%);
319
+ }
320
+ body.swal2-toast-shown .swal2-container.swal2-bottom-start, body.swal2-toast-shown .swal2-container.swal2-bottom-left {
321
+ top: auto;
322
+ right: auto;
323
+ bottom: 0;
324
+ left: 0;
325
+ }
326
+ body.swal2-toast-shown .swal2-container.swal2-bottom {
327
+ top: auto;
328
+ right: auto;
329
+ bottom: 0;
330
+ left: 50%;
331
+ -webkit-transform: translateX(-50%);
332
+ transform: translateX(-50%);
333
+ }
334
+ body.swal2-toast-shown .swal2-container.swal2-bottom-end, body.swal2-toast-shown .swal2-container.swal2-bottom-right {
335
+ top: auto;
336
+ right: 0;
337
+ bottom: 0;
338
+ left: auto;
339
+ }
340
+ body.swal2-toast-column .swal2-toast {
341
+ flex-direction: column;
342
+ align-items: stretch;
343
+ }
344
+ body.swal2-toast-column .swal2-toast .swal2-actions {
345
+ flex: 1;
346
+ align-self: stretch;
347
+ height: 2.2em;
348
+ margin-top: 0.3125em;
349
+ }
350
+ body.swal2-toast-column .swal2-toast .swal2-loading {
351
+ justify-content: center;
352
+ }
353
+ body.swal2-toast-column .swal2-toast .swal2-input {
354
+ height: 2em;
355
+ margin: 0.3125em auto;
356
+ font-size: 1em;
357
+ }
358
+ body.swal2-toast-column .swal2-toast .swal2-validation-message {
359
+ font-size: 1em;
360
+ }
361
+
362
+ .swal2-popup.swal2-toast {
363
+ flex-direction: row;
364
+ align-items: center;
365
+ width: auto;
366
+ padding: 0.625em;
367
+ overflow-y: hidden;
368
+ box-shadow: 0 0 0.625em #d9d9d9;
369
+ }
370
+ .swal2-popup.swal2-toast .swal2-header {
371
+ flex-direction: row;
372
+ }
373
+ .swal2-popup.swal2-toast .swal2-title {
374
+ flex-grow: 1;
375
+ justify-content: flex-start;
376
+ margin: 0 0.6em;
377
+ font-size: 1em;
378
+ }
379
+ .swal2-popup.swal2-toast .swal2-footer {
380
+ margin: 0.5em 0 0;
381
+ padding: 0.5em 0 0;
382
+ font-size: 0.8em;
383
+ }
384
+ .swal2-popup.swal2-toast .swal2-close {
385
+ position: initial;
386
+ width: 0.8em;
387
+ height: 0.8em;
388
+ line-height: 0.8;
389
+ }
390
+ .swal2-popup.swal2-toast .swal2-content {
391
+ justify-content: flex-start;
392
+ font-size: 1em;
393
+ }
394
+ .swal2-popup.swal2-toast .swal2-icon {
395
+ width: 2em;
396
+ min-width: 2em;
397
+ height: 2em;
398
+ margin: 0;
399
+ }
400
+ .swal2-popup.swal2-toast .swal2-icon::before {
401
+ display: flex;
402
+ align-items: center;
403
+ font-size: 2em;
404
+ font-weight: bold;
405
+ }
406
+ @media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
407
+ .swal2-popup.swal2-toast .swal2-icon::before {
408
+ font-size: 0.25em;
409
+ }
410
+ }
411
+ .swal2-popup.swal2-toast .swal2-icon.swal2-success .swal2-success-ring {
412
+ width: 2em;
413
+ height: 2em;
414
+ }
415
+ .swal2-popup.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line] {
416
+ top: 0.875em;
417
+ width: 1.375em;
418
+ }
419
+ .swal2-popup.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=left] {
420
+ left: 0.3125em;
421
+ }
422
+ .swal2-popup.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=right] {
423
+ right: 0.3125em;
424
+ }
425
+ .swal2-popup.swal2-toast .swal2-actions {
426
+ height: auto;
427
+ margin: 0 0.3125em;
428
+ }
429
+ .swal2-popup.swal2-toast .swal2-styled {
430
+ margin: 0 0.3125em;
431
+ padding: 0.3125em 0.625em;
432
+ font-size: 1em;
433
+ }
434
+ .swal2-popup.swal2-toast .swal2-styled:focus {
435
+ box-shadow: 0 0 0 0.0625em #fff, 0 0 0 0.125em rgba(50, 100, 150, 0.4);
436
+ }
437
+ .swal2-popup.swal2-toast .swal2-success {
438
+ border-color: #a5dc86;
439
+ }
440
+ .swal2-popup.swal2-toast .swal2-success [class^=swal2-success-circular-line] {
441
+ position: absolute;
442
+ width: 1.6em;
443
+ height: 3em;
444
+ -webkit-transform: rotate(45deg);
445
+ transform: rotate(45deg);
446
+ border-radius: 50%;
447
+ }
448
+ .swal2-popup.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=left] {
449
+ top: -0.8em;
450
+ left: -0.5em;
451
+ -webkit-transform: rotate(-45deg);
452
+ transform: rotate(-45deg);
453
+ -webkit-transform-origin: 2em 2em;
454
+ transform-origin: 2em 2em;
455
+ border-radius: 4em 0 0 4em;
456
+ }
457
+ .swal2-popup.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=right] {
458
+ top: -0.25em;
459
+ left: 0.9375em;
460
+ -webkit-transform-origin: 0 1.5em;
461
+ transform-origin: 0 1.5em;
462
+ border-radius: 0 4em 4em 0;
463
+ }
464
+ .swal2-popup.swal2-toast .swal2-success .swal2-success-ring {
465
+ width: 2em;
466
+ height: 2em;
467
+ }
468
+ .swal2-popup.swal2-toast .swal2-success .swal2-success-fix {
469
+ top: 0;
470
+ left: 0.4375em;
471
+ width: 0.4375em;
472
+ height: 2.6875em;
473
+ }
474
+ .swal2-popup.swal2-toast .swal2-success [class^=swal2-success-line] {
475
+ height: 0.3125em;
476
+ }
477
+ .swal2-popup.swal2-toast .swal2-success [class^=swal2-success-line][class$=tip] {
478
+ top: 1.125em;
479
+ left: 0.1875em;
480
+ width: 0.75em;
481
+ }
482
+ .swal2-popup.swal2-toast .swal2-success [class^=swal2-success-line][class$=long] {
483
+ top: 0.9375em;
484
+ right: 0.1875em;
485
+ width: 1.375em;
486
+ }
487
+ .swal2-popup.swal2-toast.swal2-show {
488
+ -webkit-animation: swal2-toast-show 0.5s;
489
+ animation: swal2-toast-show 0.5s;
490
+ }
491
+ .swal2-popup.swal2-toast.swal2-hide {
492
+ -webkit-animation: swal2-toast-hide 0.1s forwards;
493
+ animation: swal2-toast-hide 0.1s forwards;
494
+ }
495
+ .swal2-popup.swal2-toast .swal2-animate-success-icon .swal2-success-line-tip {
496
+ -webkit-animation: swal2-toast-animate-success-line-tip 0.75s;
497
+ animation: swal2-toast-animate-success-line-tip 0.75s;
498
+ }
499
+ .swal2-popup.swal2-toast .swal2-animate-success-icon .swal2-success-line-long {
500
+ -webkit-animation: swal2-toast-animate-success-line-long 0.75s;
501
+ animation: swal2-toast-animate-success-line-long 0.75s;
502
+ }
503
+
504
+ @-webkit-keyframes swal2-toast-show {
505
+ 0% {
506
+ -webkit-transform: translateY(-0.625em) rotateZ(2deg);
507
+ transform: translateY(-0.625em) rotateZ(2deg);
508
+ }
509
+ 33% {
510
+ -webkit-transform: translateY(0) rotateZ(-2deg);
511
+ transform: translateY(0) rotateZ(-2deg);
512
+ }
513
+ 66% {
514
+ -webkit-transform: translateY(0.3125em) rotateZ(2deg);
515
+ transform: translateY(0.3125em) rotateZ(2deg);
516
+ }
517
+ 100% {
518
+ -webkit-transform: translateY(0) rotateZ(0);
519
+ transform: translateY(0) rotateZ(0);
520
+ }
521
+ }
522
+
523
+ @keyframes swal2-toast-show {
524
+ 0% {
525
+ -webkit-transform: translateY(-0.625em) rotateZ(2deg);
526
+ transform: translateY(-0.625em) rotateZ(2deg);
527
+ }
528
+ 33% {
529
+ -webkit-transform: translateY(0) rotateZ(-2deg);
530
+ transform: translateY(0) rotateZ(-2deg);
531
+ }
532
+ 66% {
533
+ -webkit-transform: translateY(0.3125em) rotateZ(2deg);
534
+ transform: translateY(0.3125em) rotateZ(2deg);
535
+ }
536
+ 100% {
537
+ -webkit-transform: translateY(0) rotateZ(0);
538
+ transform: translateY(0) rotateZ(0);
539
+ }
540
+ }
541
+ @-webkit-keyframes swal2-toast-hide {
542
+ 100% {
543
+ -webkit-transform: rotateZ(1deg);
544
+ transform: rotateZ(1deg);
545
+ opacity: 0;
546
+ }
547
+ }
548
+ @keyframes swal2-toast-hide {
549
+ 100% {
550
+ -webkit-transform: rotateZ(1deg);
551
+ transform: rotateZ(1deg);
552
+ opacity: 0;
553
+ }
554
+ }
555
+ @-webkit-keyframes swal2-toast-animate-success-line-tip {
556
+ 0% {
557
+ top: 0.5625em;
558
+ left: 0.0625em;
559
+ width: 0;
560
+ }
561
+ 54% {
562
+ top: 0.125em;
563
+ left: 0.125em;
564
+ width: 0;
565
+ }
566
+ 70% {
567
+ top: 0.625em;
568
+ left: -0.25em;
569
+ width: 1.625em;
570
+ }
571
+ 84% {
572
+ top: 1.0625em;
573
+ left: 0.75em;
574
+ width: 0.5em;
575
+ }
576
+ 100% {
577
+ top: 1.125em;
578
+ left: 0.1875em;
579
+ width: 0.75em;
580
+ }
581
+ }
582
+ @keyframes swal2-toast-animate-success-line-tip {
583
+ 0% {
584
+ top: 0.5625em;
585
+ left: 0.0625em;
586
+ width: 0;
587
+ }
588
+ 54% {
589
+ top: 0.125em;
590
+ left: 0.125em;
591
+ width: 0;
592
+ }
593
+ 70% {
594
+ top: 0.625em;
595
+ left: -0.25em;
596
+ width: 1.625em;
597
+ }
598
+ 84% {
599
+ top: 1.0625em;
600
+ left: 0.75em;
601
+ width: 0.5em;
602
+ }
603
+ 100% {
604
+ top: 1.125em;
605
+ left: 0.1875em;
606
+ width: 0.75em;
607
+ }
608
+ }
609
+ @-webkit-keyframes swal2-toast-animate-success-line-long {
610
+ 0% {
611
+ top: 1.625em;
612
+ right: 1.375em;
613
+ width: 0;
614
+ }
615
+ 65% {
616
+ top: 1.25em;
617
+ right: 0.9375em;
618
+ width: 0;
619
+ }
620
+ 84% {
621
+ top: 0.9375em;
622
+ right: 0;
623
+ width: 1.125em;
624
+ }
625
+ 100% {
626
+ top: 0.9375em;
627
+ right: 0.1875em;
628
+ width: 1.375em;
629
+ }
630
+ }
631
+ @keyframes swal2-toast-animate-success-line-long {
632
+ 0% {
633
+ top: 1.625em;
634
+ right: 1.375em;
635
+ width: 0;
636
+ }
637
+ 65% {
638
+ top: 1.25em;
639
+ right: 0.9375em;
640
+ width: 0;
641
+ }
642
+ 84% {
643
+ top: 0.9375em;
644
+ right: 0;
645
+ width: 1.125em;
646
+ }
647
+ 100% {
648
+ top: 0.9375em;
649
+ right: 0.1875em;
650
+ width: 1.375em;
651
+ }
652
+ }
653
+ body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown) {
654
+ overflow: hidden;
655
+ }
656
+ body.swal2-height-auto {
657
+ height: auto !important;
658
+ }
659
+ body.swal2-no-backdrop .swal2-shown {
660
+ top: auto;
661
+ right: auto;
662
+ bottom: auto;
663
+ left: auto;
664
+ max-width: calc(100% - 0.625em * 2);
665
+ background-color: transparent;
666
+ }
667
+ body.swal2-no-backdrop .swal2-shown > .swal2-modal {
668
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.4);
669
+ }
670
+ body.swal2-no-backdrop .swal2-shown.swal2-top {
671
+ top: 0;
672
+ left: 50%;
673
+ -webkit-transform: translateX(-50%);
674
+ transform: translateX(-50%);
675
+ }
676
+ body.swal2-no-backdrop .swal2-shown.swal2-top-start, body.swal2-no-backdrop .swal2-shown.swal2-top-left {
677
+ top: 0;
678
+ left: 0;
679
+ }
680
+ body.swal2-no-backdrop .swal2-shown.swal2-top-end, body.swal2-no-backdrop .swal2-shown.swal2-top-right {
681
+ top: 0;
682
+ right: 0;
683
+ }
684
+ body.swal2-no-backdrop .swal2-shown.swal2-center {
685
+ top: 50%;
686
+ left: 50%;
687
+ -webkit-transform: translate(-50%, -50%);
688
+ transform: translate(-50%, -50%);
689
+ }
690
+ body.swal2-no-backdrop .swal2-shown.swal2-center-start, body.swal2-no-backdrop .swal2-shown.swal2-center-left {
691
+ top: 50%;
692
+ left: 0;
693
+ -webkit-transform: translateY(-50%);
694
+ transform: translateY(-50%);
695
+ }
696
+ body.swal2-no-backdrop .swal2-shown.swal2-center-end, body.swal2-no-backdrop .swal2-shown.swal2-center-right {
697
+ top: 50%;
698
+ right: 0;
699
+ -webkit-transform: translateY(-50%);
700
+ transform: translateY(-50%);
701
+ }
702
+ body.swal2-no-backdrop .swal2-shown.swal2-bottom {
703
+ bottom: 0;
704
+ left: 50%;
705
+ -webkit-transform: translateX(-50%);
706
+ transform: translateX(-50%);
707
+ }
708
+ body.swal2-no-backdrop .swal2-shown.swal2-bottom-start, body.swal2-no-backdrop .swal2-shown.swal2-bottom-left {
709
+ bottom: 0;
710
+ left: 0;
711
+ }
712
+ body.swal2-no-backdrop .swal2-shown.swal2-bottom-end, body.swal2-no-backdrop .swal2-shown.swal2-bottom-right {
713
+ right: 0;
714
+ bottom: 0;
715
+ }
716
+
717
+ .swal2-container {
718
+ display: flex;
719
+ position: fixed;
720
+ /*z-index: 1060;*/
721
+ z-index: 999999;
722
+ top: 0;
723
+ right: 0;
724
+ bottom: 0;
725
+ left: 0;
726
+ flex-direction: row;
727
+ align-items: center;
728
+ justify-content: center;
729
+ padding: 0.625em;
730
+ overflow-x: hidden;
731
+ background-color: transparent;
732
+ -webkit-overflow-scrolling: touch;
733
+ }
734
+ .swal2-container.swal2-top {
735
+ align-items: flex-start;
736
+ }
737
+ .swal2-container.swal2-top-start, .swal2-container.swal2-top-left {
738
+ align-items: flex-start;
739
+ justify-content: flex-start;
740
+ }
741
+ .swal2-container.swal2-top-end, .swal2-container.swal2-top-right {
742
+ align-items: flex-start;
743
+ justify-content: flex-end;
744
+ }
745
+ .swal2-container.swal2-center {
746
+ align-items: center;
747
+ }
748
+ .swal2-container.swal2-center-start, .swal2-container.swal2-center-left {
749
+ align-items: center;
750
+ justify-content: flex-start;
751
+ }
752
+ .swal2-container.swal2-center-end, .swal2-container.swal2-center-right {
753
+ align-items: center;
754
+ justify-content: flex-end;
755
+ }
756
+ .swal2-container.swal2-bottom {
757
+ align-items: flex-end;
758
+ }
759
+ .swal2-container.swal2-bottom-start, .swal2-container.swal2-bottom-left {
760
+ align-items: flex-end;
761
+ justify-content: flex-start;
762
+ }
763
+ .swal2-container.swal2-bottom-end, .swal2-container.swal2-bottom-right {
764
+ align-items: flex-end;
765
+ justify-content: flex-end;
766
+ }
767
+ .swal2-container.swal2-bottom > :first-child, .swal2-container.swal2-bottom-start > :first-child, .swal2-container.swal2-bottom-left > :first-child, .swal2-container.swal2-bottom-end > :first-child, .swal2-container.swal2-bottom-right > :first-child {
768
+ margin-top: auto;
769
+ }
770
+ .swal2-container.swal2-grow-fullscreen > .swal2-modal {
771
+ display: flex !important;
772
+ flex: 1;
773
+ align-self: stretch;
774
+ justify-content: center;
775
+ }
776
+ .swal2-container.swal2-grow-row > .swal2-modal {
777
+ display: flex !important;
778
+ flex: 1;
779
+ align-content: center;
780
+ justify-content: center;
781
+ }
782
+ .swal2-container.swal2-grow-column {
783
+ flex: 1;
784
+ flex-direction: column;
785
+ }
786
+ .swal2-container.swal2-grow-column.swal2-top, .swal2-container.swal2-grow-column.swal2-center, .swal2-container.swal2-grow-column.swal2-bottom {
787
+ align-items: center;
788
+ }
789
+ .swal2-container.swal2-grow-column.swal2-top-start, .swal2-container.swal2-grow-column.swal2-center-start, .swal2-container.swal2-grow-column.swal2-bottom-start, .swal2-container.swal2-grow-column.swal2-top-left, .swal2-container.swal2-grow-column.swal2-center-left, .swal2-container.swal2-grow-column.swal2-bottom-left {
790
+ align-items: flex-start;
791
+ }
792
+ .swal2-container.swal2-grow-column.swal2-top-end, .swal2-container.swal2-grow-column.swal2-center-end, .swal2-container.swal2-grow-column.swal2-bottom-end, .swal2-container.swal2-grow-column.swal2-top-right, .swal2-container.swal2-grow-column.swal2-center-right, .swal2-container.swal2-grow-column.swal2-bottom-right {
793
+ align-items: flex-end;
794
+ }
795
+ .swal2-container.swal2-grow-column > .swal2-modal {
796
+ display: flex !important;
797
+ flex: 1;
798
+ align-content: center;
799
+ justify-content: center;
800
+ }
801
+ .swal2-container:not(.swal2-top):not(.swal2-top-start):not(.swal2-top-end):not(.swal2-top-left):not(.swal2-top-right):not(.swal2-center-start):not(.swal2-center-end):not(.swal2-center-left):not(.swal2-center-right):not(.swal2-bottom):not(.swal2-bottom-start):not(.swal2-bottom-end):not(.swal2-bottom-left):not(.swal2-bottom-right):not(.swal2-grow-fullscreen) > .swal2-modal {
802
+ margin: auto;
803
+ }
804
+ @media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
805
+ .swal2-container .swal2-modal {
806
+ margin: 0 !important;
807
+ }
808
+ }
809
+ .swal2-container.swal2-fade {
810
+ transition: background-color 0.1s;
811
+ }
812
+ .swal2-container.swal2-shown {
813
+ background-color: rgba(0, 0, 0, 0.4);
814
+ }
815
+
816
+ .swal2-popup {
817
+ display: none;
818
+ position: relative;
819
+ box-sizing: border-box;
820
+ flex-direction: column;
821
+ justify-content: center;
822
+ width: 32em;
823
+ max-width: 100%;
824
+ padding: 1.25em;
825
+ border: none;
826
+ border-radius: 0.3125em;
827
+ background: #fff;
828
+ font-family: inherit;
829
+ font-size: 1rem;
830
+ }
831
+ .swal2-popup:focus {
832
+ outline: none;
833
+ }
834
+ .swal2-popup.swal2-loading {
835
+ overflow-y: hidden;
836
+ }
837
+
838
+ .swal2-header {
839
+ display: flex;
840
+ flex-direction: column;
841
+ align-items: center;
842
+ }
843
+
844
+ .swal2-title {
845
+ position: relative;
846
+ max-width: 100%;
847
+ margin: 0 0 0.4em;
848
+ padding: 0;
849
+ color: #595959;
850
+ font-size: 1.875em;
851
+ font-weight: 600;
852
+ text-align: center;
853
+ text-transform: none;
854
+ word-wrap: break-word;
855
+ }
856
+
857
+ .swal2-actions {
858
+ z-index: 1;
859
+ flex-wrap: wrap;
860
+ align-items: center;
861
+ justify-content: center;
862
+ width: 100%;
863
+ margin: 1.25em auto 0;
864
+ }
865
+ .swal2-actions:not(.swal2-loading) .swal2-styled[disabled] {
866
+ opacity: 0.4;
867
+ }
868
+ .swal2-actions:not(.swal2-loading) .swal2-styled:hover {
869
+ background-image: linear-gradient(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.1));
870
+ }
871
+ .swal2-actions:not(.swal2-loading) .swal2-styled:active {
872
+ background-image: linear-gradient(rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.2));
873
+ }
874
+ .swal2-actions.swal2-loading .swal2-styled.swal2-confirm {
875
+ box-sizing: border-box;
876
+ width: 2.5em;
877
+ height: 2.5em;
878
+ margin: 0.46875em;
879
+ padding: 0;
880
+ -webkit-animation: swal2-rotate-loading 1.5s linear 0s infinite normal;
881
+ animation: swal2-rotate-loading 1.5s linear 0s infinite normal;
882
+ border: 0.25em solid transparent;
883
+ border-radius: 100%;
884
+ border-color: transparent;
885
+ background-color: transparent !important;
886
+ color: transparent;
887
+ cursor: default;
888
+ -webkit-user-select: none;
889
+ -moz-user-select: none;
890
+ -ms-user-select: none;
891
+ user-select: none;
892
+ }
893
+ .swal2-actions.swal2-loading .swal2-styled.swal2-cancel {
894
+ margin-right: 30px;
895
+ margin-left: 30px;
896
+ }
897
+ .swal2-actions.swal2-loading :not(.swal2-styled).swal2-confirm::after {
898
+ content: "";
899
+ display: inline-block;
900
+ width: 15px;
901
+ height: 15px;
902
+ margin-left: 5px;
903
+ -webkit-animation: swal2-rotate-loading 1.5s linear 0s infinite normal;
904
+ animation: swal2-rotate-loading 1.5s linear 0s infinite normal;
905
+ border: 3px solid #999999;
906
+ border-radius: 50%;
907
+ border-right-color: transparent;
908
+ box-shadow: 1px 1px 1px #fff;
909
+ }
910
+
911
+ .swal2-styled {
912
+ margin: 0.3125em;
913
+ padding: 0.625em 2em;
914
+ box-shadow: none;
915
+ font-weight: 500;
916
+ }
917
+ .swal2-styled:not([disabled]) {
918
+ cursor: pointer;
919
+ }
920
+ .swal2-styled.swal2-confirm {
921
+ border: 0;
922
+ border-radius: 0.25em;
923
+ background: initial;
924
+ background-color: #3085d6;
925
+ color: #fff;
926
+ font-size: 1.0625em;
927
+ }
928
+ .swal2-styled.swal2-cancel {
929
+ border: 0;
930
+ border-radius: 0.25em;
931
+ background: initial;
932
+ background-color: #aaa;
933
+ color: #fff;
934
+ font-size: 1.0625em;
935
+ }
936
+ .swal2-styled:focus {
937
+ outline: none;
938
+ box-shadow: 0 0 0 2px #fff, 0 0 0 4px rgba(50, 100, 150, 0.4);
939
+ }
940
+ .swal2-styled::-moz-focus-inner {
941
+ border: 0;
942
+ }
943
+
944
+ .swal2-footer {
945
+ justify-content: center;
946
+ margin: 1.25em 0 0;
947
+ padding: 1em 0 0;
948
+ border-top: 1px solid #eee;
949
+ color: #545454;
950
+ font-size: 1em;
951
+ }
952
+
953
+ .swal2-image {
954
+ max-width: 100%;
955
+ margin: 1.25em auto;
956
+ }
957
+
958
+ .swal2-close {
959
+ position: absolute;
960
+ top: 0;
961
+ right: 0;
962
+ justify-content: center;
963
+ width: 1.2em;
964
+ height: 1.2em;
965
+ padding: 0;
966
+ overflow: hidden;
967
+ transition: color 0.1s ease-out;
968
+ border: none;
969
+ border-radius: 0;
970
+ outline: initial;
971
+ background: transparent;
972
+ color: #cccccc;
973
+ font-family: serif;
974
+ font-size: 2.5em;
975
+ line-height: 1.2;
976
+ cursor: pointer;
977
+ }
978
+ .swal2-close:hover {
979
+ -webkit-transform: none;
980
+ transform: none;
981
+ background: transparent;
982
+ color: #f27474;
983
+ }
984
+
985
+ > .swal2-input,
986
+ > .swal2-file,
987
+ > .swal2-textarea,
988
+ > .swal2-select,
989
+ > .swal2-radio,
990
+ > .swal2-checkbox {
991
+ display: none;
992
+ }
993
+
994
+ .swal2-content {
995
+ z-index: 1;
996
+ justify-content: center;
997
+ margin: 0;
998
+ padding: 0;
999
+ color: #545454;
1000
+ font-size: 1.125em;
1001
+ font-weight: 300;
1002
+ line-height: normal;
1003
+ word-wrap: break-word;
1004
+ }
1005
+
1006
+ #swal2-content {
1007
+ text-align: center;
1008
+ }
1009
+
1010
+ .swal2-input,
1011
+ .swal2-file,
1012
+ .swal2-textarea,
1013
+ .swal2-select,
1014
+ .swal2-radio,
1015
+ .swal2-checkbox {
1016
+ margin: 1em auto;
1017
+ }
1018
+
1019
+ .swal2-input,
1020
+ .swal2-file,
1021
+ .swal2-textarea {
1022
+ box-sizing: border-box;
1023
+ width: 100%;
1024
+ transition: border-color 0.3s, box-shadow 0.3s;
1025
+ border: 1px solid #d9d9d9;
1026
+ border-radius: 0.1875em;
1027
+ background: inherit;
1028
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.06);
1029
+ color: inherit;
1030
+ font-size: 1.125em;
1031
+ }
1032
+ .swal2-input.swal2-inputerror,
1033
+ .swal2-file.swal2-inputerror,
1034
+ .swal2-textarea.swal2-inputerror {
1035
+ border-color: #f27474 !important;
1036
+ box-shadow: 0 0 2px #f27474 !important;
1037
+ }
1038
+ .swal2-input:focus,
1039
+ .swal2-file:focus,
1040
+ .swal2-textarea:focus {
1041
+ border: 1px solid #b4dbed;
1042
+ outline: none;
1043
+ box-shadow: 0 0 3px #c4e6f5;
1044
+ }
1045
+ .swal2-input::-webkit-input-placeholder,
1046
+ .swal2-file::-webkit-input-placeholder,
1047
+ .swal2-textarea::-webkit-input-placeholder {
1048
+ color: #cccccc;
1049
+ }
1050
+ .swal2-input::-moz-placeholder,
1051
+ .swal2-file::-moz-placeholder,
1052
+ .swal2-textarea::-moz-placeholder {
1053
+ color: #cccccc;
1054
+ }
1055
+ .swal2-input:-ms-input-placeholder,
1056
+ .swal2-file:-ms-input-placeholder,
1057
+ .swal2-textarea:-ms-input-placeholder {
1058
+ color: #cccccc;
1059
+ }
1060
+ .swal2-input::-ms-input-placeholder,
1061
+ .swal2-file::-ms-input-placeholder,
1062
+ .swal2-textarea::-ms-input-placeholder {
1063
+ color: #cccccc;
1064
+ }
1065
+ .swal2-input::placeholder,
1066
+ .swal2-file::placeholder,
1067
+ .swal2-textarea::placeholder {
1068
+ color: #cccccc;
1069
+ }
1070
+
1071
+ .swal2-range {
1072
+ margin: 1em auto;
1073
+ background: inherit;
1074
+ }
1075
+ .swal2-range input {
1076
+ width: 80%;
1077
+ }
1078
+ .swal2-range output {
1079
+ width: 20%;
1080
+ color: inherit;
1081
+ font-weight: 600;
1082
+ text-align: center;
1083
+ }
1084
+ .swal2-range input,
1085
+ .swal2-range output {
1086
+ height: 2.625em;
1087
+ padding: 0;
1088
+ font-size: 1.125em;
1089
+ line-height: 2.625em;
1090
+ }
1091
+
1092
+ .swal2-input {
1093
+ height: 2.625em;
1094
+ padding: 0 0.75em;
1095
+ }
1096
+ .swal2-input[type=number] {
1097
+ max-width: 10em;
1098
+ }
1099
+
1100
+ .swal2-file {
1101
+ background: inherit;
1102
+ font-size: 1.125em;
1103
+ }
1104
+
1105
+ .swal2-textarea {
1106
+ height: 6.75em;
1107
+ padding: 0.75em;
1108
+ }
1109
+
1110
+ .swal2-select {
1111
+ min-width: 50%;
1112
+ max-width: 100%;
1113
+ padding: 0.375em 0.625em;
1114
+ background: inherit;
1115
+ color: inherit;
1116
+ font-size: 1.125em;
1117
+ }
1118
+
1119
+ .swal2-radio,
1120
+ .swal2-checkbox {
1121
+ align-items: center;
1122
+ justify-content: center;
1123
+ background: inherit;
1124
+ color: inherit;
1125
+ }
1126
+ .swal2-radio label,
1127
+ .swal2-checkbox label {
1128
+ margin: 0 0.6em;
1129
+ font-size: 1.125em;
1130
+ }
1131
+ .swal2-radio input,
1132
+ .swal2-checkbox input {
1133
+ margin: 0 0.4em;
1134
+ }
1135
+
1136
+ .swal2-validation-message {
1137
+ display: none;
1138
+ align-items: center;
1139
+ justify-content: center;
1140
+ padding: 0.625em;
1141
+ overflow: hidden;
1142
+ background: #f0f0f0;
1143
+ color: #666666;
1144
+ font-size: 1em;
1145
+ font-weight: 300;
1146
+ }
1147
+ .swal2-validation-message::before {
1148
+ content: "!";
1149
+ display: inline-block;
1150
+ width: 1.5em;
1151
+ min-width: 1.5em;
1152
+ height: 1.5em;
1153
+ margin: 0 0.625em;
1154
+ zoom: normal;
1155
+ border-radius: 50%;
1156
+ background-color: #f27474;
1157
+ color: #fff;
1158
+ font-weight: 600;
1159
+ line-height: 1.5em;
1160
+ text-align: center;
1161
+ }
1162
+
1163
+ @supports (-ms-accelerator: true) {
1164
+ .swal2-range input {
1165
+ width: 100% !important;
1166
+ }
1167
+ .swal2-range output {
1168
+ display: none;
1169
+ }
1170
+ }
1171
+ @media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
1172
+ .swal2-range input {
1173
+ width: 100% !important;
1174
+ }
1175
+ .swal2-range output {
1176
+ display: none;
1177
+ }
1178
+ }
1179
+ @-moz-document url-prefix() {
1180
+ .swal2-close:focus {
1181
+ outline: 2px solid rgba(50, 100, 150, 0.4);
1182
+ }
1183
+ }
1184
+ .swal2-icon {
1185
+ position: relative;
1186
+ box-sizing: content-box;
1187
+ justify-content: center;
1188
+ width: 5em;
1189
+ height: 5em;
1190
+ margin: 1.25em auto 1.875em;
1191
+ zoom: normal;
1192
+ border: 0.25em solid transparent;
1193
+ border-radius: 50%;
1194
+ line-height: 5em;
1195
+ cursor: default;
1196
+ -webkit-user-select: none;
1197
+ -moz-user-select: none;
1198
+ -ms-user-select: none;
1199
+ user-select: none;
1200
+ }
1201
+ .swal2-icon::before {
1202
+ display: flex;
1203
+ align-items: center;
1204
+ height: 92%;
1205
+ font-size: 3.75em;
1206
+ }
1207
+ .swal2-icon.swal2-error {
1208
+ border-color: #f27474;
1209
+ }
1210
+ .swal2-icon.swal2-error .swal2-x-mark {
1211
+ position: relative;
1212
+ flex-grow: 1;
1213
+ }
1214
+ .swal2-icon.swal2-error [class^=swal2-x-mark-line] {
1215
+ display: block;
1216
+ position: absolute;
1217
+ top: 2.3125em;
1218
+ width: 2.9375em;
1219
+ height: 0.3125em;
1220
+ border-radius: 0.125em;
1221
+ background-color: #f27474;
1222
+ }
1223
+ .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=left] {
1224
+ left: 1.0625em;
1225
+ -webkit-transform: rotate(45deg);
1226
+ transform: rotate(45deg);
1227
+ }
1228
+ .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=right] {
1229
+ right: 1em;
1230
+ -webkit-transform: rotate(-45deg);
1231
+ transform: rotate(-45deg);
1232
+ }
1233
+ .swal2-icon.swal2-warning {
1234
+ border-color: #facea8;
1235
+ color: #f8bb86;
1236
+ }
1237
+ .swal2-icon.swal2-warning::before {
1238
+ content: "!";
1239
+ }
1240
+ .swal2-icon.swal2-info {
1241
+ border-color: #9de0f6;
1242
+ color: #3fc3ee;
1243
+ }
1244
+ .swal2-icon.swal2-info::before {
1245
+ content: "i";
1246
+ }
1247
+ .swal2-icon.swal2-question {
1248
+ border-color: #c9dae1;
1249
+ color: #87adbd;
1250
+ }
1251
+ .swal2-icon.swal2-question::before {
1252
+ content: "?";
1253
+ }
1254
+ .swal2-icon.swal2-question.swal2-arabic-question-mark::before {
1255
+ content: "؟";
1256
+ }
1257
+ .swal2-icon.swal2-success {
1258
+ border-color: #a5dc86;
1259
+ }
1260
+ .swal2-icon.swal2-success [class^=swal2-success-circular-line] {
1261
+ position: absolute;
1262
+ width: 3.75em;
1263
+ height: 7.5em;
1264
+ -webkit-transform: rotate(45deg);
1265
+ transform: rotate(45deg);
1266
+ border-radius: 50%;
1267
+ }
1268
+ .swal2-icon.swal2-success [class^=swal2-success-circular-line][class$=left] {
1269
+ top: -0.4375em;
1270
+ left: -2.0635em;
1271
+ -webkit-transform: rotate(-45deg);
1272
+ transform: rotate(-45deg);
1273
+ -webkit-transform-origin: 3.75em 3.75em;
1274
+ transform-origin: 3.75em 3.75em;
1275
+ border-radius: 7.5em 0 0 7.5em;
1276
+ }
1277
+ .swal2-icon.swal2-success [class^=swal2-success-circular-line][class$=right] {
1278
+ top: -0.6875em;
1279
+ left: 1.875em;
1280
+ -webkit-transform: rotate(-45deg);
1281
+ transform: rotate(-45deg);
1282
+ -webkit-transform-origin: 0 3.75em;
1283
+ transform-origin: 0 3.75em;
1284
+ border-radius: 0 7.5em 7.5em 0;
1285
+ }
1286
+ .swal2-icon.swal2-success .swal2-success-ring {
1287
+ position: absolute;
1288
+ z-index: 2;
1289
+ top: -0.25em;
1290
+ left: -0.25em;
1291
+ box-sizing: content-box;
1292
+ width: 100%;
1293
+ height: 100%;
1294
+ border: 0.25em solid rgba(165, 220, 134, 0.3);
1295
+ border-radius: 50%;
1296
+ }
1297
+ .swal2-icon.swal2-success .swal2-success-fix {
1298
+ position: absolute;
1299
+ z-index: 1;
1300
+ top: 0.5em;
1301
+ left: 1.625em;
1302
+ width: 0.4375em;
1303
+ height: 5.625em;
1304
+ -webkit-transform: rotate(-45deg);
1305
+ transform: rotate(-45deg);
1306
+ }
1307
+ .swal2-icon.swal2-success [class^=swal2-success-line] {
1308
+ display: block;
1309
+ position: absolute;
1310
+ z-index: 2;
1311
+ height: 0.3125em;
1312
+ border-radius: 0.125em;
1313
+ background-color: #a5dc86;
1314
+ }
1315
+ .swal2-icon.swal2-success [class^=swal2-success-line][class$=tip] {
1316
+ top: 2.875em;
1317
+ left: 0.875em;
1318
+ width: 1.5625em;
1319
+ -webkit-transform: rotate(45deg);
1320
+ transform: rotate(45deg);
1321
+ }
1322
+ .swal2-icon.swal2-success [class^=swal2-success-line][class$=long] {
1323
+ top: 2.375em;
1324
+ right: 0.5em;
1325
+ width: 2.9375em;
1326
+ -webkit-transform: rotate(-45deg);
1327
+ transform: rotate(-45deg);
1328
+ }
1329
+
1330
+ .swal2-progress-steps {
1331
+ align-items: center;
1332
+ margin: 0 0 1.25em;
1333
+ padding: 0;
1334
+ background: inherit;
1335
+ font-weight: 600;
1336
+ }
1337
+ .swal2-progress-steps li {
1338
+ display: inline-block;
1339
+ position: relative;
1340
+ }
1341
+ .swal2-progress-steps .swal2-progress-step {
1342
+ z-index: 20;
1343
+ width: 2em;
1344
+ height: 2em;
1345
+ border-radius: 2em;
1346
+ background: #3085d6;
1347
+ color: #fff;
1348
+ line-height: 2em;
1349
+ text-align: center;
1350
+ }
1351
+ .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step {
1352
+ background: #3085d6;
1353
+ }
1354
+ .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step ~ .swal2-progress-step {
1355
+ background: #add8e6;
1356
+ color: #fff;
1357
+ }
1358
+ .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step ~ .swal2-progress-step-line {
1359
+ background: #add8e6;
1360
+ }
1361
+ .swal2-progress-steps .swal2-progress-step-line {
1362
+ z-index: 10;
1363
+ width: 2.5em;
1364
+ height: 0.4em;
1365
+ margin: 0 -1px;
1366
+ background: #3085d6;
1367
+ }
1368
+
1369
+ [class^=swal2] {
1370
+ -webkit-tap-highlight-color: transparent;
1371
+ }
1372
+
1373
+ .swal2-show {
1374
+ -webkit-animation: swal2-show 0.3s;
1375
+ animation: swal2-show 0.3s;
1376
+ }
1377
+ .swal2-show.swal2-noanimation {
1378
+ -webkit-animation: none;
1379
+ animation: none;
1380
+ }
1381
+
1382
+ .swal2-hide {
1383
+ -webkit-animation: swal2-hide 0.15s forwards;
1384
+ animation: swal2-hide 0.15s forwards;
1385
+ }
1386
+ .swal2-hide.swal2-noanimation {
1387
+ -webkit-animation: none;
1388
+ animation: none;
1389
+ }
1390
+
1391
+ .swal2-rtl .swal2-close {
1392
+ right: auto;
1393
+ left: 0;
1394
+ }
1395
+
1396
+ .swal2-animate-success-icon .swal2-success-line-tip {
1397
+ -webkit-animation: swal2-animate-success-line-tip 0.75s;
1398
+ animation: swal2-animate-success-line-tip 0.75s;
1399
+ }
1400
+ .swal2-animate-success-icon .swal2-success-line-long {
1401
+ -webkit-animation: swal2-animate-success-line-long 0.75s;
1402
+ animation: swal2-animate-success-line-long 0.75s;
1403
+ }
1404
+ .swal2-animate-success-icon .swal2-success-circular-line-right {
1405
+ -webkit-animation: swal2-rotate-success-circular-line 4.25s ease-in;
1406
+ animation: swal2-rotate-success-circular-line 4.25s ease-in;
1407
+ }
1408
+
1409
+ .swal2-animate-error-icon {
1410
+ -webkit-animation: swal2-animate-error-icon 0.5s;
1411
+ animation: swal2-animate-error-icon 0.5s;
1412
+ }
1413
+ .swal2-animate-error-icon .swal2-x-mark {
1414
+ -webkit-animation: swal2-animate-error-x-mark 0.5s;
1415
+ animation: swal2-animate-error-x-mark 0.5s;
1416
+ }
1417
+
1418
+ @-webkit-keyframes swal2-rotate-loading {
1419
+ 0% {
1420
+ -webkit-transform: rotate(0deg);
1421
+ transform: rotate(0deg);
1422
+ }
1423
+ 100% {
1424
+ -webkit-transform: rotate(360deg);
1425
+ transform: rotate(360deg);
1426
+ }
1427
+ }
1428
+
1429
+ @keyframes swal2-rotate-loading {
1430
+ 0% {
1431
+ -webkit-transform: rotate(0deg);
1432
+ transform: rotate(0deg);
1433
+ }
1434
+ 100% {
1435
+ -webkit-transform: rotate(360deg);
1436
+ transform: rotate(360deg);
1437
+ }
1438
+ }
1439
+ @media print {
1440
+ body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown) {
1441
+ overflow-y: scroll !important;
1442
+ }
1443
+ body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown) > [aria-hidden=true] {
1444
+ display: none;
1445
+ }
1446
+ body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown) .swal2-container {
1447
+ position: initial !important;
1448
+ }
1449
+ }
1450
+
1451
+ .ig-powered-by {
1452
+ font-size: 12px;
1453
+ }
includes/feedback/assets/js/sweetalert2.js ADDED
@@ -0,0 +1,2765 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ * sweetalert2 v8.11.1
3
+ * Released under the MIT License.
4
+ */
5
+ (function (global, factory) {
6
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
7
+ typeof define === 'function' && define.amd ? define(factory) :
8
+ (global.Sweetalert2 = factory());
9
+ }(this, (function () { 'use strict';
10
+
11
+ function _typeof(obj) {
12
+ if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
13
+ _typeof = function (obj) {
14
+ return typeof obj;
15
+ };
16
+ } else {
17
+ _typeof = function (obj) {
18
+ return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
19
+ };
20
+ }
21
+
22
+ return _typeof(obj);
23
+ }
24
+
25
+ function _classCallCheck(instance, Constructor) {
26
+ if (!(instance instanceof Constructor)) {
27
+ throw new TypeError("Cannot call a class as a function");
28
+ }
29
+ }
30
+
31
+ function _defineProperties(target, props) {
32
+ for (var i = 0; i < props.length; i++) {
33
+ var descriptor = props[i];
34
+ descriptor.enumerable = descriptor.enumerable || false;
35
+ descriptor.configurable = true;
36
+ if ("value" in descriptor) descriptor.writable = true;
37
+ Object.defineProperty(target, descriptor.key, descriptor);
38
+ }
39
+ }
40
+
41
+ function _createClass(Constructor, protoProps, staticProps) {
42
+ if (protoProps) _defineProperties(Constructor.prototype, protoProps);
43
+ if (staticProps) _defineProperties(Constructor, staticProps);
44
+ return Constructor;
45
+ }
46
+
47
+ function _extends() {
48
+ _extends = Object.assign || function (target) {
49
+ for (var i = 1; i < arguments.length; i++) {
50
+ var source = arguments[i];
51
+
52
+ for (var key in source) {
53
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
54
+ target[key] = source[key];
55
+ }
56
+ }
57
+ }
58
+
59
+ return target;
60
+ };
61
+
62
+ return _extends.apply(this, arguments);
63
+ }
64
+
65
+ function _inherits(subClass, superClass) {
66
+ if (typeof superClass !== "function" && superClass !== null) {
67
+ throw new TypeError("Super expression must either be null or a function");
68
+ }
69
+
70
+ subClass.prototype = Object.create(superClass && superClass.prototype, {
71
+ constructor: {
72
+ value: subClass,
73
+ writable: true,
74
+ configurable: true
75
+ }
76
+ });
77
+ if (superClass) _setPrototypeOf(subClass, superClass);
78
+ }
79
+
80
+ function _getPrototypeOf(o) {
81
+ _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
82
+ return o.__proto__ || Object.getPrototypeOf(o);
83
+ };
84
+ return _getPrototypeOf(o);
85
+ }
86
+
87
+ function _setPrototypeOf(o, p) {
88
+ _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
89
+ o.__proto__ = p;
90
+ return o;
91
+ };
92
+
93
+ return _setPrototypeOf(o, p);
94
+ }
95
+
96
+ function isNativeReflectConstruct() {
97
+ if (typeof Reflect === "undefined" || !Reflect.construct) return false;
98
+ if (Reflect.construct.sham) return false;
99
+ if (typeof Proxy === "function") return true;
100
+
101
+ try {
102
+ Date.prototype.toString.call(Reflect.construct(Date, [], function () {}));
103
+ return true;
104
+ } catch (e) {
105
+ return false;
106
+ }
107
+ }
108
+
109
+ function _construct(Parent, args, Class) {
110
+ if (isNativeReflectConstruct()) {
111
+ _construct = Reflect.construct;
112
+ } else {
113
+ _construct = function _construct(Parent, args, Class) {
114
+ var a = [null];
115
+ a.push.apply(a, args);
116
+ var Constructor = Function.bind.apply(Parent, a);
117
+ var instance = new Constructor();
118
+ if (Class) _setPrototypeOf(instance, Class.prototype);
119
+ return instance;
120
+ };
121
+ }
122
+
123
+ return _construct.apply(null, arguments);
124
+ }
125
+
126
+ function _assertThisInitialized(self) {
127
+ if (self === void 0) {
128
+ throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
129
+ }
130
+
131
+ return self;
132
+ }
133
+
134
+ function _possibleConstructorReturn(self, call) {
135
+ if (call && (typeof call === "object" || typeof call === "function")) {
136
+ return call;
137
+ }
138
+
139
+ return _assertThisInitialized(self);
140
+ }
141
+
142
+ function _superPropBase(object, property) {
143
+ while (!Object.prototype.hasOwnProperty.call(object, property)) {
144
+ object = _getPrototypeOf(object);
145
+ if (object === null) break;
146
+ }
147
+
148
+ return object;
149
+ }
150
+
151
+ function _get(target, property, receiver) {
152
+ if (typeof Reflect !== "undefined" && Reflect.get) {
153
+ _get = Reflect.get;
154
+ } else {
155
+ _get = function _get(target, property, receiver) {
156
+ var base = _superPropBase(target, property);
157
+
158
+ if (!base) return;
159
+ var desc = Object.getOwnPropertyDescriptor(base, property);
160
+
161
+ if (desc.get) {
162
+ return desc.get.call(receiver);
163
+ }
164
+
165
+ return desc.value;
166
+ };
167
+ }
168
+
169
+ return _get(target, property, receiver || target);
170
+ }
171
+
172
+ var consolePrefix = 'SweetAlert2:';
173
+ /**
174
+ * Filter the unique values into a new array
175
+ * @param arr
176
+ */
177
+
178
+ var uniqueArray = function uniqueArray(arr) {
179
+ var result = [];
180
+
181
+ for (var i = 0; i < arr.length; i++) {
182
+ if (result.indexOf(arr[i]) === -1) {
183
+ result.push(arr[i]);
184
+ }
185
+ }
186
+
187
+ return result;
188
+ };
189
+ /**
190
+ * Returns the array ob object values (Object.values isn't supported in IE11)
191
+ * @param obj
192
+ */
193
+
194
+ var objectValues = function objectValues(obj) {
195
+ return Object.keys(obj).map(function (key) {
196
+ return obj[key];
197
+ });
198
+ };
199
+ /**
200
+ * Convert NodeList to Array
201
+ * @param nodeList
202
+ */
203
+
204
+ var toArray = function toArray(nodeList) {
205
+ return Array.prototype.slice.call(nodeList);
206
+ };
207
+ /**
208
+ * Standardise console warnings
209
+ * @param message
210
+ */
211
+
212
+ var warn = function warn(message) {
213
+ console.warn("".concat(consolePrefix, " ").concat(message));
214
+ };
215
+ /**
216
+ * Standardise console errors
217
+ * @param message
218
+ */
219
+
220
+ var error = function error(message) {
221
+ console.error("".concat(consolePrefix, " ").concat(message));
222
+ };
223
+ /**
224
+ * Private global state for `warnOnce`
225
+ * @type {Array}
226
+ * @private
227
+ */
228
+
229
+ var previousWarnOnceMessages = [];
230
+ /**
231
+ * Show a console warning, but only if it hasn't already been shown
232
+ * @param message
233
+ */
234
+
235
+ var warnOnce = function warnOnce(message) {
236
+ if (!(previousWarnOnceMessages.indexOf(message) !== -1)) {
237
+ previousWarnOnceMessages.push(message);
238
+ warn(message);
239
+ }
240
+ };
241
+ /**
242
+ * Show a one-time console warning about deprecated params/methods
243
+ */
244
+
245
+ var warnAboutDepreation = function warnAboutDepreation(deprecatedParam, useInstead) {
246
+ warnOnce("\"".concat(deprecatedParam, "\" is deprecated and will be removed in the next major release. Please use \"").concat(useInstead, "\" instead."));
247
+ };
248
+ /**
249
+ * If `arg` is a function, call it (with no arguments or context) and return the result.
250
+ * Otherwise, just pass the value through
251
+ * @param arg
252
+ */
253
+
254
+ var callIfFunction = function callIfFunction(arg) {
255
+ return typeof arg === 'function' ? arg() : arg;
256
+ };
257
+ var isPromise = function isPromise(arg) {
258
+ return arg && Promise.resolve(arg) === arg;
259
+ };
260
+
261
+ var DismissReason = Object.freeze({
262
+ cancel: 'cancel',
263
+ backdrop: 'backdrop',
264
+ close: 'close',
265
+ esc: 'esc',
266
+ timer: 'timer'
267
+ });
268
+
269
+ var argsToParams = function argsToParams(args) {
270
+ var params = {};
271
+
272
+ switch (_typeof(args[0])) {
273
+ case 'object':
274
+ _extends(params, args[0]);
275
+
276
+ break;
277
+
278
+ default:
279
+ ['title', 'html', 'type'].forEach(function (name, index) {
280
+ switch (_typeof(args[index])) {
281
+ case 'string':
282
+ params[name] = args[index];
283
+ break;
284
+
285
+ case 'undefined':
286
+ break;
287
+
288
+ default:
289
+ error("Unexpected type of ".concat(name, "! Expected \"string\", got ").concat(_typeof(args[index])));
290
+ }
291
+ });
292
+ }
293
+
294
+ return params;
295
+ };
296
+
297
+ var swalPrefix = 'swal2-';
298
+ var prefix = function prefix(items) {
299
+ var result = {};
300
+
301
+ for (var i in items) {
302
+ result[items[i]] = swalPrefix + items[i];
303
+ }
304
+
305
+ return result;
306
+ };
307
+ var swalClasses = prefix(['container', 'shown', 'height-auto', 'iosfix', 'popup', 'modal', 'no-backdrop', 'toast', 'toast-shown', 'toast-column', 'fade', 'show', 'hide', 'noanimation', 'close', 'title', 'header', 'content', 'actions', 'confirm', 'cancel', 'footer', 'icon', 'image', 'input', 'file', 'range', 'select', 'radio', 'checkbox', 'label', 'textarea', 'inputerror', 'validation-message', 'progress-steps', 'active-progress-step', 'progress-step', 'progress-step-line', 'loading', 'styled', 'top', 'top-start', 'top-end', 'top-left', 'top-right', 'center', 'center-start', 'center-end', 'center-left', 'center-right', 'bottom', 'bottom-start', 'bottom-end', 'bottom-left', 'bottom-right', 'grow-row', 'grow-column', 'grow-fullscreen', 'rtl']);
308
+ var iconTypes = prefix(['success', 'warning', 'info', 'question', 'error']);
309
+
310
+ var states = {
311
+ previousBodyPadding: null
312
+ };
313
+ var hasClass = function hasClass(elem, className) {
314
+ return elem.classList.contains(className);
315
+ };
316
+ var applyCustomClass = function applyCustomClass(elem, customClass, className) {
317
+ // Clean up previous custom classes
318
+ toArray(elem.classList).forEach(function (className) {
319
+ if (!(objectValues(swalClasses).indexOf(className) !== -1) && !(objectValues(iconTypes).indexOf(className) !== -1)) {
320
+ elem.classList.remove(className);
321
+ }
322
+ });
323
+
324
+ if (customClass && customClass[className]) {
325
+ addClass(elem, customClass[className]);
326
+ }
327
+ };
328
+ function getInput(content, inputType) {
329
+ if (!inputType) {
330
+ return null;
331
+ }
332
+
333
+ switch (inputType) {
334
+ case 'select':
335
+ case 'textarea':
336
+ case 'file':
337
+ return getChildByClass(content, swalClasses[inputType]);
338
+
339
+ case 'checkbox':
340
+ return content.querySelector(".".concat(swalClasses.checkbox, " input"));
341
+
342
+ case 'radio':
343
+ return content.querySelector(".".concat(swalClasses.radio, " input:checked")) || content.querySelector(".".concat(swalClasses.radio, " input:first-child"));
344
+
345
+ case 'range':
346
+ return content.querySelector(".".concat(swalClasses.range, " input"));
347
+
348
+ default:
349
+ return getChildByClass(content, swalClasses.input);
350
+ }
351
+ }
352
+ var focusInput = function focusInput(input) {
353
+ input.focus(); // place cursor at end of text in text input
354
+
355
+ if (input.type !== 'file') {
356
+ // http://stackoverflow.com/a/2345915
357
+ var val = input.value;
358
+ input.value = '';
359
+ input.value = val;
360
+ }
361
+ };
362
+ var toggleClass = function toggleClass(target, classList, condition) {
363
+ if (!target || !classList) {
364
+ return;
365
+ }
366
+
367
+ if (typeof classList === 'string') {
368
+ classList = classList.split(/\s+/).filter(Boolean);
369
+ }
370
+
371
+ classList.forEach(function (className) {
372
+ if (target.forEach) {
373
+ target.forEach(function (elem) {
374
+ condition ? elem.classList.add(className) : elem.classList.remove(className);
375
+ });
376
+ } else {
377
+ condition ? target.classList.add(className) : target.classList.remove(className);
378
+ }
379
+ });
380
+ };
381
+ var addClass = function addClass(target, classList) {
382
+ toggleClass(target, classList, true);
383
+ };
384
+ var removeClass = function removeClass(target, classList) {
385
+ toggleClass(target, classList, false);
386
+ };
387
+ var getChildByClass = function getChildByClass(elem, className) {
388
+ for (var i = 0; i < elem.childNodes.length; i++) {
389
+ if (hasClass(elem.childNodes[i], className)) {
390
+ return elem.childNodes[i];
391
+ }
392
+ }
393
+ };
394
+ var applyNumericalStyle = function applyNumericalStyle(elem, property, value) {
395
+ if (value || parseInt(value) === 0) {
396
+ elem.style[property] = typeof value === 'number' ? value + 'px' : value;
397
+ } else {
398
+ elem.style.removeProperty(property);
399
+ }
400
+ };
401
+ var show = function show(elem) {
402
+ var display = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'flex';
403
+ elem.style.opacity = '';
404
+ elem.style.display = display;
405
+ };
406
+ var hide = function hide(elem) {
407
+ elem.style.opacity = '';
408
+ elem.style.display = 'none';
409
+ };
410
+ var toggle = function toggle(elem, condition, display) {
411
+ condition ? show(elem, display) : hide(elem);
412
+ }; // borrowed from jquery $(elem).is(':visible') implementation
413
+
414
+ var isVisible = function isVisible(elem) {
415
+ return !!(elem && (elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length));
416
+ }; // borrowed from https://stackoverflow.com/a/46352119
417
+
418
+ var hasCssAnimation = function hasCssAnimation(elem) {
419
+ var style = window.getComputedStyle(elem);
420
+ var animDuration = parseFloat(style.getPropertyValue('animation-duration') || '0');
421
+ var transDuration = parseFloat(style.getPropertyValue('transition-duration') || '0');
422
+ return animDuration > 0 || transDuration > 0;
423
+ };
424
+ var contains = function contains(haystack, needle) {
425
+ if (typeof haystack.contains === 'function') {
426
+ return haystack.contains(needle);
427
+ }
428
+ };
429
+
430
+ var getContainer = function getContainer() {
431
+ return document.body.querySelector('.' + swalClasses.container);
432
+ };
433
+ var elementBySelector = function elementBySelector(selectorString) {
434
+ var container = getContainer();
435
+ return container ? container.querySelector(selectorString) : null;
436
+ };
437
+
438
+ var elementByClass = function elementByClass(className) {
439
+ return elementBySelector('.' + className);
440
+ };
441
+
442
+ var getPopup = function getPopup() {
443
+ return elementByClass(swalClasses.popup);
444
+ };
445
+ var getIcons = function getIcons() {
446
+ var popup = getPopup();
447
+ return toArray(popup.querySelectorAll('.' + swalClasses.icon));
448
+ };
449
+ var getIcon = function getIcon() {
450
+ var visibleIcon = getIcons().filter(function (icon) {
451
+ return isVisible(icon);
452
+ });
453
+ return visibleIcon.length ? visibleIcon[0] : null;
454
+ };
455
+ var getTitle = function getTitle() {
456
+ return elementByClass(swalClasses.title);
457
+ };
458
+ var getContent = function getContent() {
459
+ return elementByClass(swalClasses.content);
460
+ };
461
+ var getImage = function getImage() {
462
+ return elementByClass(swalClasses.image);
463
+ };
464
+ var getProgressSteps = function getProgressSteps() {
465
+ return elementByClass(swalClasses['progress-steps']);
466
+ };
467
+ var getValidationMessage = function getValidationMessage() {
468
+ return elementByClass(swalClasses['validation-message']);
469
+ };
470
+ var getConfirmButton = function getConfirmButton() {
471
+ return elementBySelector('.' + swalClasses.actions + ' .' + swalClasses.confirm);
472
+ };
473
+ var getCancelButton = function getCancelButton() {
474
+ return elementBySelector('.' + swalClasses.actions + ' .' + swalClasses.cancel);
475
+ };
476
+ var getActions = function getActions() {
477
+ return elementByClass(swalClasses.actions);
478
+ };
479
+ var getHeader = function getHeader() {
480
+ return elementByClass(swalClasses.header);
481
+ };
482
+ var getFooter = function getFooter() {
483
+ return elementByClass(swalClasses.footer);
484
+ };
485
+ var getCloseButton = function getCloseButton() {
486
+ return elementByClass(swalClasses.close);
487
+ };
488
+ var getFocusableElements = function getFocusableElements() {
489
+ var focusableElementsWithTabindex = toArray(getPopup().querySelectorAll('[tabindex]:not([tabindex="-1"]):not([tabindex="0"])')) // sort according to tabindex
490
+ .sort(function (a, b) {
491
+ a = parseInt(a.getAttribute('tabindex'));
492
+ b = parseInt(b.getAttribute('tabindex'));
493
+
494
+ if (a > b) {
495
+ return 1;
496
+ } else if (a < b) {
497
+ return -1;
498
+ }
499
+
500
+ return 0;
501
+ }); // https://github.com/jkup/focusable/blob/master/index.js
502
+
503
+ var otherFocusableElements = toArray(getPopup().querySelectorAll('a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, [tabindex="0"], [contenteditable], audio[controls], video[controls]')).filter(function (el) {
504
+ return el.getAttribute('tabindex') !== '-1';
505
+ });
506
+ return uniqueArray(focusableElementsWithTabindex.concat(otherFocusableElements)).filter(function (el) {
507
+ return isVisible(el);
508
+ });
509
+ };
510
+ var isModal = function isModal() {
511
+ return !isToast() && !document.body.classList.contains(swalClasses['no-backdrop']);
512
+ };
513
+ var isToast = function isToast() {
514
+ return document.body.classList.contains(swalClasses['toast-shown']);
515
+ };
516
+ var isLoading = function isLoading() {
517
+ return getPopup().hasAttribute('data-loading');
518
+ };
519
+
520
+ // Detect Node env
521
+ var isNodeEnv = function isNodeEnv() {
522
+ return typeof window === 'undefined' || typeof document === 'undefined';
523
+ };
524
+
525
+ var sweetHTML = "\n <div aria-labelledby=\"".concat(swalClasses.title, "\" aria-describedby=\"").concat(swalClasses.content, "\" class=\"").concat(swalClasses.popup, "\" tabindex=\"-1\">\n <div class=\"").concat(swalClasses.header, "\">\n <ul class=\"").concat(swalClasses['progress-steps'], "\"></ul>\n <div class=\"").concat(swalClasses.icon, " ").concat(iconTypes.error, "\">\n <span class=\"swal2-x-mark\"><span class=\"swal2-x-mark-line-left\"></span><span class=\"swal2-x-mark-line-right\"></span></span>\n </div>\n <div class=\"").concat(swalClasses.icon, " ").concat(iconTypes.question, "\"></div>\n <div class=\"").concat(swalClasses.icon, " ").concat(iconTypes.warning, "\"></div>\n <div class=\"").concat(swalClasses.icon, " ").concat(iconTypes.info, "\"></div>\n <div class=\"").concat(swalClasses.icon, " ").concat(iconTypes.success, "\">\n <div class=\"swal2-success-circular-line-left\"></div>\n <span class=\"swal2-success-line-tip\"></span> <span class=\"swal2-success-line-long\"></span>\n <div class=\"swal2-success-ring\"></div> <div class=\"swal2-success-fix\"></div>\n <div class=\"swal2-success-circular-line-right\"></div>\n </div>\n <img class=\"").concat(swalClasses.image, "\" />\n <h2 class=\"").concat(swalClasses.title, "\" id=\"").concat(swalClasses.title, "\"></h2>\n <button type=\"button\" class=\"").concat(swalClasses.close, "\">&times;</button>\n </div>\n <div class=\"").concat(swalClasses.content, "\">\n <div id=\"").concat(swalClasses.content, "\"></div>\n <input class=\"").concat(swalClasses.input, "\" />\n <input type=\"file\" class=\"").concat(swalClasses.file, "\" />\n <div class=\"").concat(swalClasses.range, "\">\n <input type=\"range\" />\n <output></output>\n </div>\n <select class=\"").concat(swalClasses.select, "\"></select>\n <div class=\"").concat(swalClasses.radio, "\"></div>\n <label for=\"").concat(swalClasses.checkbox, "\" class=\"").concat(swalClasses.checkbox, "\">\n <input type=\"checkbox\" />\n <span class=\"").concat(swalClasses.label, "\"></span>\n </label>\n <textarea class=\"").concat(swalClasses.textarea, "\"></textarea>\n <div class=\"").concat(swalClasses['validation-message'], "\" id=\"").concat(swalClasses['validation-message'], "\"></div>\n </div>\n <div class=\"").concat(swalClasses.actions, "\">\n <button type=\"button\" class=\"").concat(swalClasses.confirm, "\">OK</button>\n <button type=\"button\" class=\"").concat(swalClasses.cancel, "\">Cancel</button>\n </div>\n <div class=\"").concat(swalClasses.footer, "\">\n </div>\n </div>\n").replace(/(^|\n)\s*/g, '');
526
+
527
+ var resetOldContainer = function resetOldContainer() {
528
+ var oldContainer = getContainer();
529
+
530
+ if (!oldContainer) {
531
+ return;
532
+ }
533
+
534
+ oldContainer.parentNode.removeChild(oldContainer);
535
+ removeClass([document.documentElement, document.body], [swalClasses['no-backdrop'], swalClasses['toast-shown'], swalClasses['has-column']]);
536
+ };
537
+
538
+ var oldInputVal; // IE11 workaround, see #1109 for details
539
+
540
+ var resetValidationMessage = function resetValidationMessage(e) {
541
+ if (Swal.isVisible() && oldInputVal !== e.target.value) {
542
+ Swal.resetValidationMessage();
543
+ }
544
+
545
+ oldInputVal = e.target.value;
546
+ };
547
+
548
+ var addInputChangeListeners = function addInputChangeListeners() {
549
+ var content = getContent();
550
+ var input = getChildByClass(content, swalClasses.input);
551
+ var file = getChildByClass(content, swalClasses.file);
552
+ var range = content.querySelector(".".concat(swalClasses.range, " input"));
553
+ var rangeOutput = content.querySelector(".".concat(swalClasses.range, " output"));
554
+ var select = getChildByClass(content, swalClasses.select);
555
+ var checkbox = content.querySelector(".".concat(swalClasses.checkbox, " input"));
556
+ var textarea = getChildByClass(content, swalClasses.textarea);
557
+ input.oninput = resetValidationMessage;
558
+ file.onchange = resetValidationMessage;
559
+ select.onchange = resetValidationMessage;
560
+ checkbox.onchange = resetValidationMessage;
561
+ textarea.oninput = resetValidationMessage;
562
+
563
+ range.oninput = function (e) {
564
+ resetValidationMessage(e);
565
+ rangeOutput.value = range.value;
566
+ };
567
+
568
+ range.onchange = function (e) {
569
+ resetValidationMessage(e);
570
+ range.nextSibling.value = range.value;
571
+ };
572
+ };
573
+
574
+ var getTarget = function getTarget(target) {
575
+ return typeof target === 'string' ? document.querySelector(target) : target;
576
+ };
577
+
578
+ var setupAccessibility = function setupAccessibility(params) {
579
+ var popup = getPopup();
580
+ popup.setAttribute('role', params.toast ? 'alert' : 'dialog');
581
+ popup.setAttribute('aria-live', params.toast ? 'polite' : 'assertive');
582
+
583
+ if (!params.toast) {
584
+ popup.setAttribute('aria-modal', 'true');
585
+ }
586
+ };
587
+
588
+ var setupRTL = function setupRTL(targetElement) {
589
+ if (window.getComputedStyle(targetElement).direction === 'rtl') {
590
+ addClass(getContainer(), swalClasses.rtl);
591
+ }
592
+ };
593
+ /*
594
+ * Add modal + backdrop to DOM
595
+ */
596
+
597
+
598
+ var init = function init(params) {
599
+ // Clean up the old popup container if it exists
600
+ resetOldContainer();
601
+ /* istanbul ignore if */
602
+
603
+ if (isNodeEnv()) {
604
+ error('SweetAlert2 requires document to initialize');
605
+ return;
606
+ }
607
+
608
+ var container = document.createElement('div');
609
+ container.className = swalClasses.container;
610
+ container.innerHTML = sweetHTML;
611
+ var targetElement = getTarget(params.target);
612
+ targetElement.appendChild(container);
613
+ setupAccessibility(params);
614
+ setupRTL(targetElement);
615
+ addInputChangeListeners();
616
+ };
617
+
618
+ var parseHtmlToContainer = function parseHtmlToContainer(param, target) {
619
+ // DOM element
620
+ if (param instanceof HTMLElement) {
621
+ target.appendChild(param); // JQuery element(s)
622
+ } else if (_typeof(param) === 'object') {
623
+ handleJqueryElem(target, param); // Plain string
624
+ } else if (param) {
625
+ target.innerHTML = param;
626
+ }
627
+ };
628
+
629
+ var handleJqueryElem = function handleJqueryElem(target, elem) {
630
+ target.innerHTML = '';
631
+
632
+ if (0 in elem) {
633
+ for (var i = 0; i in elem; i++) {
634
+ target.appendChild(elem[i].cloneNode(true));
635
+ }
636
+ } else {
637
+ target.appendChild(elem.cloneNode(true));
638
+ }
639
+ };
640
+
641
+ var animationEndEvent = function () {
642
+ // Prevent run in Node env
643
+
644
+ /* istanbul ignore if */
645
+ if (isNodeEnv()) {
646
+ return false;
647
+ }
648
+
649
+ var testEl = document.createElement('div');
650
+ var transEndEventNames = {
651
+ 'WebkitAnimation': 'webkitAnimationEnd',
652
+ 'OAnimation': 'oAnimationEnd oanimationend',
653
+ 'animation': 'animationend'
654
+ };
655
+
656
+ for (var i in transEndEventNames) {
657
+ if (transEndEventNames.hasOwnProperty(i) && typeof testEl.style[i] !== 'undefined') {
658
+ return transEndEventNames[i];
659
+ }
660
+ }
661
+
662
+ return false;
663
+ }();
664
+
665
+ // Measure width of scrollbar
666
+ // https://github.com/twbs/bootstrap/blob/master/js/modal.js#L279-L286
667
+ var measureScrollbar = function measureScrollbar() {
668
+ var supportsTouch = 'ontouchstart' in window || navigator.msMaxTouchPoints;
669
+
670
+ if (supportsTouch) {
671
+ return 0;
672
+ }
673
+
674
+ var scrollDiv = document.createElement('div');
675
+ scrollDiv.style.width = '50px';
676
+ scrollDiv.style.height = '50px';
677
+ scrollDiv.style.overflow = 'scroll';
678
+ document.body.appendChild(scrollDiv);
679
+ var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
680
+ document.body.removeChild(scrollDiv);
681
+ return scrollbarWidth;
682
+ };
683
+
684
+ function handleButtonsStyling(confirmButton, cancelButton, params) {
685
+ addClass([confirmButton, cancelButton], swalClasses.styled); // Buttons background colors
686
+
687
+ if (params.confirmButtonColor) {
688
+ confirmButton.style.backgroundColor = params.confirmButtonColor;
689
+ }
690
+
691
+ if (params.cancelButtonColor) {
692
+ cancelButton.style.backgroundColor = params.cancelButtonColor;
693
+ } // Loading state
694
+
695
+
696
+ var confirmButtonBackgroundColor = window.getComputedStyle(confirmButton).getPropertyValue('background-color');
697
+ confirmButton.style.borderLeftColor = confirmButtonBackgroundColor;
698
+ confirmButton.style.borderRightColor = confirmButtonBackgroundColor;
699
+ }
700
+
701
+ function renderButton(button, buttonType, params) {
702
+ toggle(button, params['showC' + buttonType.substring(1) + 'Button'], 'inline-block');
703
+ button.innerHTML = params[buttonType + 'ButtonText']; // Set caption text
704
+
705
+ button.setAttribute('aria-label', params[buttonType + 'ButtonAriaLabel']); // ARIA label
706
+ // Add buttons custom classes
707
+
708
+ button.className = swalClasses[buttonType];
709
+ applyCustomClass(button, params.customClass, buttonType + 'Button');
710
+ addClass(button, params[buttonType + 'ButtonClass']);
711
+ }
712
+
713
+ var renderActions = function renderActions(instance, params) {
714
+ var actions = getActions();
715
+ var confirmButton = getConfirmButton();
716
+ var cancelButton = getCancelButton(); // Actions (buttons) wrapper
717
+
718
+ if (!params.showConfirmButton && !params.showCancelButton) {
719
+ hide(actions);
720
+ } else {
721
+ show(actions);
722
+ } // Custom class
723
+
724
+
725
+ applyCustomClass(actions, params.customClass, 'actions'); // Render confirm button
726
+
727
+ renderButton(confirmButton, 'confirm', params); // render Cancel Button
728
+
729
+ renderButton(cancelButton, 'cancel', params);
730
+
731
+ if (params.buttonsStyling) {
732
+ handleButtonsStyling(confirmButton, cancelButton, params);
733
+ } else {
734
+ removeClass([confirmButton, cancelButton], swalClasses.styled);
735
+ confirmButton.style.backgroundColor = confirmButton.style.borderLeftColor = confirmButton.style.borderRightColor = '';
736
+ cancelButton.style.backgroundColor = cancelButton.style.borderLeftColor = cancelButton.style.borderRightColor = '';
737
+ }
738
+ };
739
+
740
+ function handleBackdropParam(container, backdrop) {
741
+ if (typeof backdrop === 'string') {
742
+ container.style.background = backdrop;
743
+ } else if (!backdrop) {
744
+ addClass([document.documentElement, document.body], swalClasses['no-backdrop']);
745
+ }
746
+ }
747
+
748
+ function handlePositionParam(container, position) {
749
+ if (position in swalClasses) {
750
+ addClass(container, swalClasses[position]);
751
+ } else {
752
+ warn('The "position" parameter is not valid, defaulting to "center"');
753
+ addClass(container, swalClasses.center);
754
+ }
755
+ }
756
+
757
+ function handleGrowParam(container, grow) {
758
+ if (grow && typeof grow === 'string') {
759
+ var growClass = 'grow-' + grow;
760
+
761
+ if (growClass in swalClasses) {
762
+ addClass(container, swalClasses[growClass]);
763
+ }
764
+ }
765
+ }
766
+
767
+ var renderContainer = function renderContainer(instance, params) {
768
+ var container = getContainer();
769
+
770
+ if (!container) {
771
+ return;
772
+ }
773
+
774
+ handleBackdropParam(container, params.backdrop);
775
+
776
+ if (!params.backdrop && params.allowOutsideClick) {
777
+ warn('"allowOutsideClick" parameter requires `backdrop` parameter to be set to `true`');
778
+ }
779
+
780
+ handlePositionParam(container, params.position);
781
+ handleGrowParam(container, params.grow); // Custom class
782
+
783
+ applyCustomClass(container, params.customClass, 'container');
784
+
785
+ if (params.customContainerClass) {
786
+ // @deprecated
787
+ addClass(container, params.customContainerClass);
788
+ }
789
+ };
790
+
791
+ /**
792
+ * This module containts `WeakMap`s for each effectively-"private property" that a `Swal` has.
793
+ * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')`
794
+ * This is the approach that Babel will probably take to implement private methods/fields
795
+ * https://github.com/tc39/proposal-private-methods
796
+ * https://github.com/babel/babel/pull/7555
797
+ * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module*
798
+ * then we can use that language feature.
799
+ */
800
+ var privateProps = {
801
+ promise: new WeakMap(),
802
+ innerParams: new WeakMap(),
803
+ domCache: new WeakMap()
804
+ };
805
+
806
+ var renderInput = function renderInput(instance, params) {
807
+ var innerParams = privateProps.innerParams.get(instance);
808
+ var rerender = !innerParams || params.input !== innerParams.input;
809
+ var content = getContent();
810
+ var inputTypes = ['input', 'file', 'range', 'select', 'radio', 'checkbox', 'textarea'];
811
+
812
+ for (var i = 0; i < inputTypes.length; i++) {
813
+ var inputClass = swalClasses[inputTypes[i]];
814
+ var inputContainer = getChildByClass(content, inputClass); // set attributes
815
+
816
+ setAttributes(inputTypes[i], params.inputAttributes); // set class
817
+
818
+ setClass(inputContainer, inputClass, params);
819
+ rerender && hide(inputContainer);
820
+ }
821
+
822
+ if (!params.input) {
823
+ return;
824
+ }
825
+
826
+ if (!renderInputType[params.input]) {
827
+ return error("Unexpected type of input! Expected \"text\", \"email\", \"password\", \"number\", \"tel\", \"select\", \"radio\", \"checkbox\", \"textarea\", \"file\" or \"url\", got \"".concat(params.input, "\""));
828
+ }
829
+
830
+ if (rerender) {
831
+ var input = renderInputType[params.input](params);
832
+ show(input);
833
+ }
834
+ };
835
+
836
+ var removeAttributes = function removeAttributes(input) {
837
+ for (var i = 0; i < input.attributes.length; i++) {
838
+ var attrName = input.attributes[i].name;
839
+
840
+ if (!(['type', 'value', 'style'].indexOf(attrName) !== -1)) {
841
+ input.removeAttribute(attrName);
842
+ }
843
+ }
844
+ };
845
+
846
+ var setAttributes = function setAttributes(inputType, inputAttributes) {
847
+ var input = getInput(getContent(), inputType);
848
+
849
+ if (!input) {
850
+ return;
851
+ }
852
+
853
+ removeAttributes(input);
854
+
855
+ for (var attr in inputAttributes) {
856
+ // Do not set a placeholder for <input type="range">
857
+ // it'll crash Edge, #1298
858
+ if (inputType === 'range' && attr === 'placeholder') {
859
+ continue;
860
+ }
861
+
862
+ input.setAttribute(attr, inputAttributes[attr]);
863
+ }
864
+ };
865
+
866
+ var setClass = function setClass(inputContainer, inputClass, params) {
867
+ inputContainer.className = inputClass;
868
+
869
+ if (params.inputClass) {
870
+ addClass(inputContainer, params.inputClass);
871
+ }
872
+
873
+ if (params.customClass) {
874
+ addClass(inputContainer, params.customClass.input);
875
+ }
876
+ };
877
+
878
+ var setInputPlaceholder = function setInputPlaceholder(input, params) {
879
+ if (!input.placeholder || params.inputPlaceholder) {
880
+ input.placeholder = params.inputPlaceholder;
881
+ }
882
+ };
883
+
884
+ var renderInputType = {};
885
+
886
+ renderInputType.text = renderInputType.email = renderInputType.password = renderInputType.number = renderInputType.tel = renderInputType.url = function (params) {
887
+ var input = getChildByClass(getContent(), swalClasses.input);
888
+
889
+ if (typeof params.inputValue === 'string' || typeof params.inputValue === 'number') {
890
+ input.value = params.inputValue;
891
+ } else if (!isPromise(params.inputValue)) {
892
+ warn("Unexpected type of inputValue! Expected \"string\", \"number\" or \"Promise\", got \"".concat(_typeof(params.inputValue), "\""));
893
+ }
894
+
895
+ setInputPlaceholder(input, params);
896
+ input.type = params.input;
897
+ return input;
898
+ };
899
+
900
+ renderInputType.file = function (params) {
901
+ var input = getChildByClass(getContent(), swalClasses.file);
902
+ setInputPlaceholder(input, params);
903
+ input.type = params.input;
904
+ return input;
905
+ };
906
+
907
+ renderInputType.range = function (params) {
908
+ var range = getChildByClass(getContent(), swalClasses.range);
909
+ var rangeInput = range.querySelector('input');
910
+ var rangeOutput = range.querySelector('output');
911
+ rangeInput.value = params.inputValue;
912
+ rangeInput.type = params.input;
913
+ rangeOutput.value = params.inputValue;
914
+ return range;
915
+ };
916
+
917
+ renderInputType.select = function (params) {
918
+ var select = getChildByClass(getContent(), swalClasses.select);
919
+ select.innerHTML = '';
920
+
921
+ if (params.inputPlaceholder) {
922
+ var placeholder = document.createElement('option');
923
+ placeholder.innerHTML = params.inputPlaceholder;
924
+ placeholder.value = '';
925
+ placeholder.disabled = true;
926
+ placeholder.selected = true;
927
+ select.appendChild(placeholder);
928
+ }
929
+
930
+ return select;
931
+ };
932
+
933
+ renderInputType.radio = function () {
934
+ var radio = getChildByClass(getContent(), swalClasses.radio);
935
+ radio.innerHTML = '';
936
+ return radio;
937
+ };
938
+
939
+ renderInputType.checkbox = function (params) {
940
+ var checkbox = getChildByClass(getContent(), swalClasses.checkbox);
941
+ var checkboxInput = getInput(getContent(), 'checkbox');
942
+ checkboxInput.type = 'checkbox';
943
+ checkboxInput.value = 1;
944
+ checkboxInput.id = swalClasses.checkbox;
945
+ checkboxInput.checked = Boolean(params.inputValue);
946
+ var label = checkbox.querySelector('span');
947
+ label.innerHTML = params.inputPlaceholder;
948
+ return checkbox;
949
+ };
950
+
951
+ renderInputType.textarea = function (params) {
952
+ var textarea = getChildByClass(getContent(), swalClasses.textarea);
953
+ textarea.value = params.inputValue;
954
+ setInputPlaceholder(textarea, params);
955
+ return textarea;
956
+ };
957
+
958
+ var renderContent = function renderContent(instance, params) {
959
+ var content = getContent().querySelector('#' + swalClasses.content); // Content as HTML
960
+
961
+ if (params.html) {
962
+ parseHtmlToContainer(params.html, content);
963
+ show(content, 'block'); // Content as plain text
964
+ } else if (params.text) {
965
+ content.textContent = params.text;
966
+ show(content, 'block'); // No content
967
+ } else {
968
+ hide(content);
969
+ }
970
+
971
+ renderInput(instance, params); // Custom class
972
+
973
+ applyCustomClass(getContent(), params.customClass, 'content');
974
+ };
975
+
976
+ var renderFooter = function renderFooter(instance, params) {
977
+ var footer = getFooter();
978
+ toggle(footer, params.footer);
979
+
980
+ if (params.footer) {
981
+ parseHtmlToContainer(params.footer, footer);
982
+ } // Custom class
983
+
984
+
985
+ applyCustomClass(footer, params.customClass, 'footer');
986
+ };
987
+
988
+ var renderCloseButton = function renderCloseButton(instance, params) {
989
+ var closeButton = getCloseButton(); // Custom class
990
+
991
+ applyCustomClass(closeButton, params.customClass, 'closeButton');
992
+ toggle(closeButton, params.showCloseButton);
993
+ closeButton.setAttribute('aria-label', params.closeButtonAriaLabel);
994
+ };
995
+
996
+ var renderIcon = function renderIcon(instance, params) {
997
+ var innerParams = privateProps.innerParams.get(instance); // if the icon with the given type already rendered,
998
+ // apply the custom class without re-rendering the icon
999
+
1000
+ if (innerParams && params.type === innerParams.type && getIcon()) {
1001
+ applyCustomClass(getIcon(), params.customClass, 'icon');
1002
+ return;
1003
+ }
1004
+
1005
+ hideAllIcons();
1006
+
1007
+ if (!params.type) {
1008
+ return;
1009
+ }
1010
+
1011
+ adjustSuccessIconBackgoundColor();
1012
+
1013
+ if (Object.keys(iconTypes).indexOf(params.type) !== -1) {
1014
+ var icon = elementBySelector(".".concat(swalClasses.icon, ".").concat(iconTypes[params.type]));
1015
+ show(icon); // Custom class
1016
+
1017
+ applyCustomClass(icon, params.customClass, 'icon'); // Animate icon
1018
+
1019
+ toggleClass(icon, "swal2-animate-".concat(params.type, "-icon"), params.animation);
1020
+ } else {
1021
+ error("Unknown type! Expected \"success\", \"error\", \"warning\", \"info\" or \"question\", got \"".concat(params.type, "\""));
1022
+ }
1023
+ };
1024
+
1025
+ var hideAllIcons = function hideAllIcons() {
1026
+ var icons = getIcons();
1027
+
1028
+ for (var i = 0; i < icons.length; i++) {
1029
+ hide(icons[i]);
1030
+ }
1031
+ }; // Adjust success icon background color to match the popup background color
1032
+
1033
+
1034
+ var adjustSuccessIconBackgoundColor = function adjustSuccessIconBackgoundColor() {
1035
+ var popup = getPopup();
1036
+ var popupBackgroundColor = window.getComputedStyle(popup).getPropertyValue('background-color');
1037
+ var successIconParts = popup.querySelectorAll('[class^=swal2-success-circular-line], .swal2-success-fix');
1038
+
1039
+ for (var i = 0; i < successIconParts.length; i++) {
1040
+ successIconParts[i].style.backgroundColor = popupBackgroundColor;
1041
+ }
1042
+ };
1043
+
1044
+ var renderImage = function renderImage(instance, params) {
1045
+ var image = getImage();
1046
+
1047
+ if (!params.imageUrl) {
1048
+ return hide(image);
1049
+ }
1050
+
1051
+ show(image); // Src, alt
1052
+
1053
+ image.setAttribute('src', params.imageUrl);
1054
+ image.setAttribute('alt', params.imageAlt); // Width, height
1055
+
1056
+ applyNumericalStyle(image, 'width', params.imageWidth);
1057
+ applyNumericalStyle(image, 'height', params.imageHeight); // Class
1058
+
1059
+ image.className = swalClasses.image;
1060
+ applyCustomClass(image, params.customClass, 'image');
1061
+
1062
+ if (params.imageClass) {
1063
+ addClass(image, params.imageClass);
1064
+ }
1065
+ };
1066
+
1067
+ var createStepElement = function createStepElement(step) {
1068
+ var stepEl = document.createElement('li');
1069
+ addClass(stepEl, swalClasses['progress-step']);
1070
+ stepEl.innerHTML = step;
1071
+ return stepEl;
1072
+ };
1073
+
1074
+ var createLineElement = function createLineElement(params) {
1075
+ var lineEl = document.createElement('li');
1076
+ addClass(lineEl, swalClasses['progress-step-line']);
1077
+
1078
+ if (params.progressStepsDistance) {
1079
+ lineEl.style.width = params.progressStepsDistance;
1080
+ }
1081
+
1082
+ return lineEl;
1083
+ };
1084
+
1085
+ var renderProgressSteps = function renderProgressSteps(instance, params) {
1086
+ var progressStepsContainer = getProgressSteps();
1087
+
1088
+ if (!params.progressSteps || params.progressSteps.length === 0) {
1089
+ return hide(progressStepsContainer);
1090
+ }
1091
+
1092
+ show(progressStepsContainer);
1093
+ progressStepsContainer.innerHTML = '';
1094
+ var currentProgressStep = parseInt(params.currentProgressStep === null ? Swal.getQueueStep() : params.currentProgressStep);
1095
+
1096
+ if (currentProgressStep >= params.progressSteps.length) {
1097
+ warn('Invalid currentProgressStep parameter, it should be less than progressSteps.length ' + '(currentProgressStep like JS arrays starts from 0)');
1098
+ }
1099
+
1100
+ params.progressSteps.forEach(function (step, index) {
1101
+ var stepEl = createStepElement(step);
1102
+ progressStepsContainer.appendChild(stepEl);
1103
+
1104
+ if (index === currentProgressStep) {
1105
+ addClass(stepEl, swalClasses['active-progress-step']);
1106
+ }
1107
+
1108
+ if (index !== params.progressSteps.length - 1) {
1109
+ var lineEl = createLineElement(step);
1110
+ progressStepsContainer.appendChild(lineEl);
1111
+ }
1112
+ });
1113
+ };
1114
+
1115
+ var renderTitle = function renderTitle(instance, params) {
1116
+ var title = getTitle();
1117
+ toggle(title, params.title || params.titleText);
1118
+
1119
+ if (params.title) {
1120
+ parseHtmlToContainer(params.title, title);
1121
+ }
1122
+
1123
+ if (params.titleText) {
1124
+ title.innerText = params.titleText;
1125
+ } // Custom class
1126
+
1127
+
1128
+ applyCustomClass(title, params.customClass, 'title');
1129
+ };
1130
+
1131
+ var renderHeader = function renderHeader(instance, params) {
1132
+ var header = getHeader(); // Custom class
1133
+
1134
+ applyCustomClass(header, params.customClass, 'header'); // Progress steps
1135
+
1136
+ renderProgressSteps(instance, params); // Icon
1137
+
1138
+ renderIcon(instance, params); // Image
1139
+
1140
+ renderImage(instance, params); // Title
1141
+
1142
+ renderTitle(instance, params); // Close button
1143
+
1144
+ renderCloseButton(instance, params);
1145
+ };
1146
+
1147
+ var renderPopup = function renderPopup(instance, params) {
1148
+ var popup = getPopup(); // Width
1149
+
1150
+ applyNumericalStyle(popup, 'width', params.width); // Padding
1151
+
1152
+ applyNumericalStyle(popup, 'padding', params.padding); // Background
1153
+
1154
+ if (params.background) {
1155
+ popup.style.background = params.background;
1156
+ } // Default Class
1157
+
1158
+
1159
+ popup.className = swalClasses.popup;
1160
+
1161
+ if (params.toast) {
1162
+ addClass([document.documentElement, document.body], swalClasses['toast-shown']);
1163
+ addClass(popup, swalClasses.toast);
1164
+ } else {
1165
+ addClass(popup, swalClasses.modal);
1166
+ } // Custom class
1167
+
1168
+
1169
+ applyCustomClass(popup, params.customClass, 'popup');
1170
+
1171
+ if (typeof params.customClass === 'string') {
1172
+ addClass(popup, params.customClass);
1173
+ } // CSS animation
1174
+
1175
+
1176
+ toggleClass(popup, swalClasses.noanimation, !params.animation);
1177
+ };
1178
+
1179
+ var render = function render(instance, params) {
1180
+ renderPopup(instance, params);
1181
+ renderContainer(instance, params);
1182
+ renderHeader(instance, params);
1183
+ renderContent(instance, params);
1184
+ renderActions(instance, params);
1185
+ renderFooter(instance, params);
1186
+ };
1187
+
1188
+ /*
1189
+ * Global function to determine if SweetAlert2 popup is shown
1190
+ */
1191
+
1192
+ var isVisible$1 = function isVisible$$1() {
1193
+ return isVisible(getPopup());
1194
+ };
1195
+ /*
1196
+ * Global function to click 'Confirm' button
1197
+ */
1198
+
1199
+ var clickConfirm = function clickConfirm() {
1200
+ return getConfirmButton() && getConfirmButton().click();
1201
+ };
1202
+ /*
1203
+ * Global function to click 'Cancel' button
1204
+ */
1205
+
1206
+ var clickCancel = function clickCancel() {
1207
+ return getCancelButton() && getCancelButton().click();
1208
+ };
1209
+
1210
+ function fire() {
1211
+ var Swal = this;
1212
+
1213
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
1214
+ args[_key] = arguments[_key];
1215
+ }
1216
+
1217
+ return _construct(Swal, args);
1218
+ }
1219
+
1220
+ /**
1221
+ * Returns an extended version of `Swal` containing `params` as defaults.
1222
+ * Useful for reusing Swal configuration.
1223
+ *
1224
+ * For example:
1225
+ *
1226
+ * Before:
1227
+ * const textPromptOptions = { input: 'text', showCancelButton: true }
1228
+ * const {value: firstName} = await Swal.fire({ ...textPromptOptions, title: 'What is your first name?' })
1229
+ * const {value: lastName} = await Swal.fire({ ...textPromptOptions, title: 'What is your last name?' })
1230
+ *
1231
+ * After:
1232
+ * const TextPrompt = Swal.mixin({ input: 'text', showCancelButton: true })
1233
+ * const {value: firstName} = await TextPrompt('What is your first name?')
1234
+ * const {value: lastName} = await TextPrompt('What is your last name?')
1235
+ *
1236
+ * @param mixinParams
1237
+ */
1238
+ function mixin(mixinParams) {
1239
+ var MixinSwal =
1240
+ /*#__PURE__*/
1241
+ function (_this) {
1242
+ _inherits(MixinSwal, _this);
1243
+
1244
+ function MixinSwal() {
1245
+ _classCallCheck(this, MixinSwal);
1246
+
1247
+ return _possibleConstructorReturn(this, _getPrototypeOf(MixinSwal).apply(this, arguments));
1248
+ }
1249
+
1250
+ _createClass(MixinSwal, [{
1251
+ key: "_main",
1252
+ value: function _main(params) {
1253
+ return _get(_getPrototypeOf(MixinSwal.prototype), "_main", this).call(this, _extends({}, mixinParams, params));
1254
+ }
1255
+ }]);
1256
+
1257
+ return MixinSwal;
1258
+ }(this);
1259
+
1260
+ return MixinSwal;
1261
+ }
1262
+
1263
+ // private global state for the queue feature
1264
+ var currentSteps = [];
1265
+ /*
1266
+ * Global function for chaining sweetAlert popups
1267
+ */
1268
+
1269
+ var queue = function queue(steps) {
1270
+ var Swal = this;
1271
+ currentSteps = steps;
1272
+
1273
+ var resetAndResolve = function resetAndResolve(resolve, value) {
1274
+ currentSteps = [];
1275
+ document.body.removeAttribute('data-swal2-queue-step');
1276
+ resolve(value);
1277
+ };
1278
+
1279
+ var queueResult = [];
1280
+ return new Promise(function (resolve) {
1281
+ (function step(i, callback) {
1282
+ if (i < currentSteps.length) {
1283
+ document.body.setAttribute('data-swal2-queue-step', i);
1284
+ Swal.fire(currentSteps[i]).then(function (result) {
1285
+ if (typeof result.value !== 'undefined') {
1286
+ queueResult.push(result.value);
1287
+ step(i + 1, callback);
1288
+ } else {
1289
+ resetAndResolve(resolve, {
1290
+ dismiss: result.dismiss
1291
+ });
1292
+ }
1293
+ });
1294
+ } else {
1295
+ resetAndResolve(resolve, {
1296
+ value: queueResult
1297
+ });
1298
+ }
1299
+ })(0);
1300
+ });
1301
+ };
1302
+ /*
1303
+ * Global function for getting the index of current popup in queue
1304
+ */
1305
+
1306
+ var getQueueStep = function getQueueStep() {
1307
+ return document.body.getAttribute('data-swal2-queue-step');
1308
+ };
1309
+ /*
1310
+ * Global function for inserting a popup to the queue
1311
+ */
1312
+
1313
+ var insertQueueStep = function insertQueueStep(step, index) {
1314
+ if (index && index < currentSteps.length) {
1315
+ return currentSteps.splice(index, 0, step);
1316
+ }
1317
+
1318
+ return currentSteps.push(step);
1319
+ };
1320
+ /*
1321
+ * Global function for deleting a popup from the queue
1322
+ */
1323
+
1324
+ var deleteQueueStep = function deleteQueueStep(index) {
1325
+ if (typeof currentSteps[index] !== 'undefined') {
1326
+ currentSteps.splice(index, 1);
1327
+ }
1328
+ };
1329
+
1330
+ /**
1331
+ * Show spinner instead of Confirm button and disable Cancel button
1332
+ */
1333
+
1334
+ var showLoading = function showLoading() {
1335
+ var popup = getPopup();
1336
+
1337
+ if (!popup) {
1338
+ Swal.fire('');
1339
+ }
1340
+
1341
+ popup = getPopup();
1342
+ var actions = getActions();
1343
+ var confirmButton = getConfirmButton();
1344
+ var cancelButton = getCancelButton();
1345
+ show(actions);
1346
+ show(confirmButton);
1347
+ addClass([popup, actions], swalClasses.loading);
1348
+ confirmButton.disabled = true;
1349
+ cancelButton.disabled = true;
1350
+ popup.setAttribute('data-loading', true);
1351
+ popup.setAttribute('aria-busy', true);
1352
+ popup.focus();
1353
+ };
1354
+
1355
+ var RESTORE_FOCUS_TIMEOUT = 100;
1356
+
1357
+ var globalState = {};
1358
+ var focusPreviousActiveElement = function focusPreviousActiveElement() {
1359
+ if (globalState.previousActiveElement && globalState.previousActiveElement.focus) {
1360
+ globalState.previousActiveElement.focus();
1361
+ globalState.previousActiveElement = null;
1362
+ } else if (document.body) {
1363
+ document.body.focus();
1364
+ }
1365
+ }; // Restore previous active (focused) element
1366
+
1367
+
1368
+ var restoreActiveElement = function restoreActiveElement() {
1369
+ return new Promise(function (resolve) {
1370
+ var x = window.scrollX;
1371
+ var y = window.scrollY;
1372
+ globalState.restoreFocusTimeout = setTimeout(function () {
1373
+ focusPreviousActiveElement();
1374
+ resolve();
1375
+ }, RESTORE_FOCUS_TIMEOUT); // issues/900
1376
+
1377
+ if (typeof x !== 'undefined' && typeof y !== 'undefined') {
1378
+ // IE doesn't have scrollX/scrollY support
1379
+ window.scrollTo(x, y);
1380
+ }
1381
+ });
1382
+ };
1383
+
1384
+ /**
1385
+ * If `timer` parameter is set, returns number of milliseconds of timer remained.
1386
+ * Otherwise, returns undefined.
1387
+ */
1388
+
1389
+ var getTimerLeft = function getTimerLeft() {
1390
+ return globalState.timeout && globalState.timeout.getTimerLeft();
1391
+ };
1392
+ /**
1393
+ * Stop timer. Returns number of milliseconds of timer remained.
1394
+ * If `timer` parameter isn't set, returns undefined.
1395
+ */
1396
+
1397
+ var stopTimer = function stopTimer() {
1398
+ return globalState.timeout && globalState.timeout.stop();
1399
+ };
1400
+ /**
1401
+ * Resume timer. Returns number of milliseconds of timer remained.
1402
+ * If `timer` parameter isn't set, returns undefined.
1403
+ */
1404
+
1405
+ var resumeTimer = function resumeTimer() {
1406
+ return globalState.timeout && globalState.timeout.start();
1407
+ };
1408
+ /**
1409
+ * Resume timer. Returns number of milliseconds of timer remained.
1410
+ * If `timer` parameter isn't set, returns undefined.
1411
+ */
1412
+
1413
+ var toggleTimer = function toggleTimer() {
1414
+ var timer = globalState.timeout;
1415
+ return timer && (timer.running ? timer.stop() : timer.start());
1416
+ };
1417
+ /**
1418
+ * Increase timer. Returns number of milliseconds of an updated timer.
1419
+ * If `timer` parameter isn't set, returns undefined.
1420
+ */
1421
+
1422
+ var increaseTimer = function increaseTimer(n) {
1423
+ return globalState.timeout && globalState.timeout.increase(n);
1424
+ };
1425
+ /**
1426
+ * Check if timer is running. Returns true if timer is running
1427
+ * or false if timer is paused or stopped.
1428
+ * If `timer` parameter isn't set, returns undefined
1429
+ */
1430
+
1431
+ var isTimerRunning = function isTimerRunning() {
1432
+ return globalState.timeout && globalState.timeout.isRunning();
1433
+ };
1434
+
1435
+ var defaultParams = {
1436
+ title: '',
1437
+ titleText: '',
1438
+ text: '',
1439
+ html: '',
1440
+ footer: '',
1441
+ type: null,
1442
+ toast: false,
1443
+ customClass: '',
1444
+ customContainerClass: '',
1445
+ target: 'body',
1446
+ backdrop: true,
1447
+ animation: true,
1448
+ heightAuto: true,
1449
+ allowOutsideClick: true,
1450
+ allowEscapeKey: true,
1451
+ allowEnterKey: true,
1452
+ stopKeydownPropagation: true,
1453
+ keydownListenerCapture: false,
1454
+ showConfirmButton: true,
1455
+ showCancelButton: false,
1456
+ preConfirm: null,
1457
+ confirmButtonText: 'OK',
1458
+ confirmButtonAriaLabel: '',
1459
+ confirmButtonColor: null,
1460
+ confirmButtonClass: '',
1461
+ cancelButtonText: 'Cancel',
1462
+ cancelButtonAriaLabel: '',
1463
+ cancelButtonColor: null,
1464
+ cancelButtonClass: '',
1465
+ buttonsStyling: true,
1466
+ reverseButtons: false,
1467
+ focusConfirm: true,
1468
+ focusCancel: false,
1469
+ showCloseButton: false,
1470
+ closeButtonAriaLabel: 'Close this dialog',
1471
+ showLoaderOnConfirm: false,
1472
+ imageUrl: null,
1473
+ imageWidth: null,
1474
+ imageHeight: null,
1475
+ imageAlt: '',
1476
+ imageClass: '',
1477
+ timer: null,
1478
+ width: null,
1479
+ padding: null,
1480
+ background: null,
1481
+ input: null,
1482
+ inputPlaceholder: '',
1483
+ inputValue: '',
1484
+ inputOptions: {},
1485
+ inputAutoTrim: true,
1486
+ inputClass: '',
1487
+ inputAttributes: {},
1488
+ inputValidator: null,
1489
+ validationMessage: null,
1490
+ grow: false,
1491
+ position: 'center',
1492
+ progressSteps: [],
1493
+ currentProgressStep: null,
1494
+ progressStepsDistance: null,
1495
+ onBeforeOpen: null,
1496
+ onAfterClose: null,
1497
+ onOpen: null,
1498
+ onClose: null,
1499
+ scrollbarPadding: true
1500
+ };
1501
+ var updatableParams = ['title', 'titleText', 'text', 'html', 'type', 'customClass', 'showConfirmButton', 'showCancelButton', 'confirmButtonText', 'confirmButtonAriaLabel', 'confirmButtonColor', 'confirmButtonClass', 'cancelButtonText', 'cancelButtonAriaLabel', 'cancelButtonColor', 'cancelButtonClass', 'buttonsStyling', 'reverseButtons', 'imageUrl', 'imageWidth', 'imageHeigth', 'imageAlt', 'imageClass', 'progressSteps', 'currentProgressStep'];
1502
+ var deprecatedParams = {
1503
+ customContainerClass: 'customClass',
1504
+ confirmButtonClass: 'customClass',
1505
+ cancelButtonClass: 'customClass',
1506
+ imageClass: 'customClass',
1507
+ inputClass: 'customClass'
1508
+ };
1509
+ var toastIncompatibleParams = ['allowOutsideClick', 'allowEnterKey', 'backdrop', 'focusConfirm', 'focusCancel', 'heightAuto', 'keydownListenerCapture'];
1510
+ /**
1511
+ * Is valid parameter
1512
+ * @param {String} paramName
1513
+ */
1514
+
1515
+ var isValidParameter = function isValidParameter(paramName) {
1516
+ return defaultParams.hasOwnProperty(paramName);
1517
+ };
1518
+ /**
1519
+ * Is valid parameter for Swal.update() method
1520
+ * @param {String} paramName
1521
+ */
1522
+
1523
+ var isUpdatableParameter = function isUpdatableParameter(paramName) {
1524
+ return updatableParams.indexOf(paramName) !== -1;
1525
+ };
1526
+ /**
1527
+ * Is deprecated parameter
1528
+ * @param {String} paramName
1529
+ */
1530
+
1531
+ var isDeprecatedParameter = function isDeprecatedParameter(paramName) {
1532
+ return deprecatedParams[paramName];
1533
+ };
1534
+
1535
+ var checkIfParamIsValid = function checkIfParamIsValid(param) {
1536
+ if (!isValidParameter(param)) {
1537
+ warn("Unknown parameter \"".concat(param, "\""));
1538
+ }
1539
+ };
1540
+
1541
+ var checkIfToastParamIsValid = function checkIfToastParamIsValid(param) {
1542
+ if (toastIncompatibleParams.indexOf(param) !== -1) {
1543
+ warn("The parameter \"".concat(param, "\" is incompatible with toasts"));
1544
+ }
1545
+ };
1546
+
1547
+ var checkIfParamIsDeprecated = function checkIfParamIsDeprecated(param) {
1548
+ if (isDeprecatedParameter(param)) {
1549
+ warnAboutDepreation(param, isDeprecatedParameter(param));
1550
+ }
1551
+ };
1552
+ /**
1553
+ * Show relevant warnings for given params
1554
+ *
1555
+ * @param params
1556
+ */
1557
+
1558
+
1559
+ var showWarningsForParams = function showWarningsForParams(params) {
1560
+ for (var param in params) {
1561
+ checkIfParamIsValid(param);
1562
+
1563
+ if (params.toast) {
1564
+ checkIfToastParamIsValid(param);
1565
+ }
1566
+
1567
+ checkIfParamIsDeprecated();
1568
+ }
1569
+ };
1570
+
1571
+
1572
+
1573
+ var staticMethods = Object.freeze({
1574
+ isValidParameter: isValidParameter,
1575
+ isUpdatableParameter: isUpdatableParameter,
1576
+ isDeprecatedParameter: isDeprecatedParameter,
1577
+ argsToParams: argsToParams,
1578
+ isVisible: isVisible$1,
1579
+ clickConfirm: clickConfirm,
1580
+ clickCancel: clickCancel,
1581
+ getContainer: getContainer,
1582
+ getPopup: getPopup,
1583
+ getTitle: getTitle,
1584
+ getContent: getContent,
1585
+ getImage: getImage,
1586
+ getIcon: getIcon,
1587
+ getIcons: getIcons,
1588
+ getCloseButton: getCloseButton,
1589
+ getActions: getActions,
1590
+ getConfirmButton: getConfirmButton,
1591
+ getCancelButton: getCancelButton,
1592
+ getHeader: getHeader,
1593
+ getFooter: getFooter,
1594
+ getFocusableElements: getFocusableElements,
1595
+ getValidationMessage: getValidationMessage,
1596
+ isLoading: isLoading,
1597
+ fire: fire,
1598
+ mixin: mixin,
1599
+ queue: queue,
1600
+ getQueueStep: getQueueStep,
1601
+ insertQueueStep: insertQueueStep,
1602
+ deleteQueueStep: deleteQueueStep,
1603
+ showLoading: showLoading,
1604
+ enableLoading: showLoading,
1605
+ getTimerLeft: getTimerLeft,
1606
+ stopTimer: stopTimer,
1607
+ resumeTimer: resumeTimer,
1608
+ toggleTimer: toggleTimer,
1609
+ increaseTimer: increaseTimer,
1610
+ isTimerRunning: isTimerRunning
1611
+ });
1612
+
1613
+ /**
1614
+ * Enables buttons and hide loader.
1615
+ */
1616
+
1617
+ function hideLoading() {
1618
+ var innerParams = privateProps.innerParams.get(this);
1619
+ var domCache = privateProps.domCache.get(this);
1620
+
1621
+ if (!innerParams.showConfirmButton) {
1622
+ hide(domCache.confirmButton);
1623
+
1624
+ if (!innerParams.showCancelButton) {
1625
+ hide(domCache.actions);
1626
+ }
1627
+ }
1628
+
1629
+ removeClass([domCache.popup, domCache.actions], swalClasses.loading);
1630
+ domCache.popup.removeAttribute('aria-busy');
1631
+ domCache.popup.removeAttribute('data-loading');
1632
+ domCache.confirmButton.disabled = false;
1633
+ domCache.cancelButton.disabled = false;
1634
+ }
1635
+
1636
+ function getInput$1(instance) {
1637
+ var innerParams = privateProps.innerParams.get(instance || this);
1638
+ var domCache = privateProps.domCache.get(instance || this);
1639
+ return getInput(domCache.content, innerParams.input);
1640
+ }
1641
+
1642
+ var fixScrollbar = function fixScrollbar() {
1643
+ // for queues, do not do this more than once
1644
+ if (states.previousBodyPadding !== null) {
1645
+ return;
1646
+ } // if the body has overflow
1647
+
1648
+
1649
+ if (document.body.scrollHeight > window.innerHeight) {
1650
+ // add padding so the content doesn't shift after removal of scrollbar
1651
+ states.previousBodyPadding = parseInt(window.getComputedStyle(document.body).getPropertyValue('padding-right'));
1652
+ document.body.style.paddingRight = states.previousBodyPadding + measureScrollbar() + 'px';
1653
+ }
1654
+ };
1655
+ var undoScrollbar = function undoScrollbar() {
1656
+ if (states.previousBodyPadding !== null) {
1657
+ document.body.style.paddingRight = states.previousBodyPadding + 'px';
1658
+ states.previousBodyPadding = null;
1659
+ }
1660
+ };
1661
+
1662
+ /* istanbul ignore next */
1663
+
1664
+ var iOSfix = function iOSfix() {
1665
+ var iOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
1666
+
1667
+ if (iOS && !hasClass(document.body, swalClasses.iosfix)) {
1668
+ var offset = document.body.scrollTop;
1669
+ document.body.style.top = offset * -1 + 'px';
1670
+ addClass(document.body, swalClasses.iosfix);
1671
+ }
1672
+ };
1673
+ /* istanbul ignore next */
1674
+
1675
+ var undoIOSfix = function undoIOSfix() {
1676
+ if (hasClass(document.body, swalClasses.iosfix)) {
1677
+ var offset = parseInt(document.body.style.top, 10);
1678
+ removeClass(document.body, swalClasses.iosfix);
1679
+ document.body.style.top = '';
1680
+ document.body.scrollTop = offset * -1;
1681
+ }
1682
+ };
1683
+
1684
+ var isIE11 = function isIE11() {
1685
+ return !!window.MSInputMethodContext && !!document.documentMode;
1686
+ }; // Fix IE11 centering sweetalert2/issues/933
1687
+
1688
+ /* istanbul ignore next */
1689
+
1690
+
1691
+ var fixVerticalPositionIE = function fixVerticalPositionIE() {
1692
+ var container = getContainer();
1693
+ var popup = getPopup();
1694
+ container.style.removeProperty('align-items');
1695
+
1696
+ if (popup.offsetTop < 0) {
1697
+ container.style.alignItems = 'flex-start';
1698
+ }
1699
+ };
1700
+ /* istanbul ignore next */
1701
+
1702
+
1703
+ var IEfix = function IEfix() {
1704
+ if (typeof window !== 'undefined' && isIE11()) {
1705
+ fixVerticalPositionIE();
1706
+ window.addEventListener('resize', fixVerticalPositionIE);
1707
+ }
1708
+ };
1709
+ /* istanbul ignore next */
1710
+
1711
+ var undoIEfix = function undoIEfix() {
1712
+ if (typeof window !== 'undefined' && isIE11()) {
1713
+ window.removeEventListener('resize', fixVerticalPositionIE);
1714
+ }
1715
+ };
1716
+
1717
+ // Adding aria-hidden="true" to elements outside of the active modal dialog ensures that
1718
+ // elements not within the active modal dialog will not be surfaced if a user opens a screen
1719
+ // reader’s list of elements (headings, form controls, landmarks, etc.) in the document.
1720
+
1721
+ var setAriaHidden = function setAriaHidden() {
1722
+ var bodyChildren = toArray(document.body.children);
1723
+ bodyChildren.forEach(function (el) {
1724
+ if (el === getContainer() || contains(el, getContainer())) {
1725
+ return;
1726
+ }
1727
+
1728
+ if (el.hasAttribute('aria-hidden')) {
1729
+ el.setAttribute('data-previous-aria-hidden', el.getAttribute('aria-hidden'));
1730
+ }
1731
+
1732
+ el.setAttribute('aria-hidden', 'true');
1733
+ });
1734
+ };
1735
+ var unsetAriaHidden = function unsetAriaHidden() {
1736
+ var bodyChildren = toArray(document.body.children);
1737
+ bodyChildren.forEach(function (el) {
1738
+ if (el.hasAttribute('data-previous-aria-hidden')) {
1739
+ el.setAttribute('aria-hidden', el.getAttribute('data-previous-aria-hidden'));
1740
+ el.removeAttribute('data-previous-aria-hidden');
1741
+ } else {
1742
+ el.removeAttribute('aria-hidden');
1743
+ }
1744
+ });
1745
+ };
1746
+
1747
+ /**
1748
+ * This module containts `WeakMap`s for each effectively-"private property" that a `Swal` has.
1749
+ * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')`
1750
+ * This is the approach that Babel will probably take to implement private methods/fields
1751
+ * https://github.com/tc39/proposal-private-methods
1752
+ * https://github.com/babel/babel/pull/7555
1753
+ * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module*
1754
+ * then we can use that language feature.
1755
+ */
1756
+ var privateMethods = {
1757
+ swalPromiseResolve: new WeakMap()
1758
+ };
1759
+
1760
+ /*
1761
+ * Instance method to close sweetAlert
1762
+ */
1763
+
1764
+ function removePopupAndResetState(container, isToast, onAfterClose) {
1765
+ if (isToast) {
1766
+ triggerOnAfterClose(onAfterClose);
1767
+ } else {
1768
+ restoreActiveElement().then(function () {
1769
+ return triggerOnAfterClose(onAfterClose);
1770
+ });
1771
+ globalState.keydownTarget.removeEventListener('keydown', globalState.keydownHandler, {
1772
+ capture: globalState.keydownListenerCapture
1773
+ });
1774
+ globalState.keydownHandlerAdded = false;
1775
+ } // Unset globalState props so GC will dispose globalState (#1569)
1776
+
1777
+
1778
+ delete globalState.keydownHandler;
1779
+ delete globalState.keydownTarget;
1780
+
1781
+ if (container.parentNode) {
1782
+ container.parentNode.removeChild(container);
1783
+ }
1784
+
1785
+ removeBodyClasses();
1786
+
1787
+ if (isModal()) {
1788
+ undoScrollbar();
1789
+ undoIOSfix();
1790
+ undoIEfix();
1791
+ unsetAriaHidden();
1792
+ }
1793
+ }
1794
+
1795
+ function removeBodyClasses() {
1796
+ removeClass([document.documentElement, document.body], [swalClasses.shown, swalClasses['height-auto'], swalClasses['no-backdrop'], swalClasses['toast-shown'], swalClasses['toast-column']]);
1797
+ }
1798
+
1799
+ function swalCloseEventFinished(popup, container, isToast, onAfterClose) {
1800
+ popup.removeEventListener(animationEndEvent, swalCloseEventFinished);
1801
+
1802
+ if (hasClass(popup, swalClasses.hide)) {
1803
+ removePopupAndResetState(container, isToast, onAfterClose);
1804
+ } // Unset WeakMaps so GC will be able to dispose them (#1569)
1805
+
1806
+
1807
+ unsetWeakMaps(privateProps);
1808
+ unsetWeakMaps(privateMethods);
1809
+ }
1810
+
1811
+ function close(resolveValue) {
1812
+ var container = getContainer();
1813
+ var popup = getPopup();
1814
+
1815
+ if (!popup || hasClass(popup, swalClasses.hide)) {
1816
+ return;
1817
+ }
1818
+
1819
+ var innerParams = privateProps.innerParams.get(this);
1820
+ var swalPromiseResolve = privateMethods.swalPromiseResolve.get(this);
1821
+ var onClose = innerParams.onClose;
1822
+ var onAfterClose = innerParams.onAfterClose;
1823
+ removeClass(popup, swalClasses.show);
1824
+ addClass(popup, swalClasses.hide); // If animation is supported, animate
1825
+
1826
+ if (animationEndEvent && hasCssAnimation(popup)) {
1827
+ popup.addEventListener(animationEndEvent, swalCloseEventFinished.bind(null, popup, container, isToast(), onAfterClose));
1828
+ } else {
1829
+ // Otherwise, remove immediately
1830
+ removePopupAndResetState(container, isToast(), onAfterClose);
1831
+ }
1832
+
1833
+ if (onClose !== null && typeof onClose === 'function') {
1834
+ onClose(popup);
1835
+ } // Resolve Swal promise
1836
+
1837
+
1838
+ swalPromiseResolve(resolveValue || {}); // Unset this.params so GC will dispose it (#1569)
1839
+
1840
+ delete this.params;
1841
+ }
1842
+
1843
+ var unsetWeakMaps = function unsetWeakMaps(obj) {
1844
+ for (var i in obj) {
1845
+ obj[i] = new WeakMap();
1846
+ }
1847
+ };
1848
+
1849
+ var triggerOnAfterClose = function triggerOnAfterClose(onAfterClose) {
1850
+ if (onAfterClose !== null && typeof onAfterClose === 'function') {
1851
+ setTimeout(function () {
1852
+ onAfterClose();
1853
+ });
1854
+ }
1855
+ };
1856
+
1857
+ function setButtonsDisabled(instance, buttons, disabled) {
1858
+ var domCache = privateProps.domCache.get(instance);
1859
+ buttons.forEach(function (button) {
1860
+ domCache[button].disabled = disabled;
1861
+ });
1862
+ }
1863
+
1864
+ function setInputDisabled(input, disabled) {
1865
+ if (!input) {
1866
+ return false;
1867
+ }
1868
+
1869
+ if (input.type === 'radio') {
1870
+ var radiosContainer = input.parentNode.parentNode;
1871
+ var radios = radiosContainer.querySelectorAll('input');
1872
+
1873
+ for (var i = 0; i < radios.length; i++) {
1874
+ radios[i].disabled = disabled;
1875
+ }
1876
+ } else {
1877
+ input.disabled = disabled;
1878
+ }
1879
+ }
1880
+
1881
+ function enableButtons() {
1882
+ setButtonsDisabled(this, ['confirmButton', 'cancelButton'], false);
1883
+ }
1884
+ function disableButtons() {
1885
+ setButtonsDisabled(this, ['confirmButton', 'cancelButton'], true);
1886
+ } // @deprecated
1887
+
1888
+ function enableConfirmButton() {
1889
+ warnAboutDepreation('Swal.disableConfirmButton()', "Swal.getConfirmButton().removeAttribute('disabled')");
1890
+ setButtonsDisabled(this, ['confirmButton'], false);
1891
+ } // @deprecated
1892
+
1893
+ function disableConfirmButton() {
1894
+ warnAboutDepreation('Swal.enableConfirmButton()', "Swal.getConfirmButton().setAttribute('disabled', '')");
1895
+ setButtonsDisabled(this, ['confirmButton'], true);
1896
+ }
1897
+ function enableInput() {
1898
+ return setInputDisabled(this.getInput(), false);
1899
+ }
1900
+ function disableInput() {
1901
+ return setInputDisabled(this.getInput(), true);
1902
+ }
1903
+
1904
+ function showValidationMessage(error) {
1905
+ var domCache = privateProps.domCache.get(this);
1906
+ domCache.validationMessage.innerHTML = error;
1907
+ var popupComputedStyle = window.getComputedStyle(domCache.popup);
1908
+ domCache.validationMessage.style.marginLeft = "-".concat(popupComputedStyle.getPropertyValue('padding-left'));
1909
+ domCache.validationMessage.style.marginRight = "-".concat(popupComputedStyle.getPropertyValue('padding-right'));
1910
+ show(domCache.validationMessage);
1911
+ var input = this.getInput();
1912
+
1913
+ if (input) {
1914
+ input.setAttribute('aria-invalid', true);
1915
+ input.setAttribute('aria-describedBy', swalClasses['validation-message']);
1916
+ focusInput(input);
1917
+ addClass(input, swalClasses.inputerror);
1918
+ }
1919
+ } // Hide block with validation message
1920
+
1921
+ function resetValidationMessage$1() {
1922
+ var domCache = privateProps.domCache.get(this);
1923
+
1924
+ if (domCache.validationMessage) {
1925
+ hide(domCache.validationMessage);
1926
+ }
1927
+
1928
+ var input = this.getInput();
1929
+
1930
+ if (input) {
1931
+ input.removeAttribute('aria-invalid');
1932
+ input.removeAttribute('aria-describedBy');
1933
+ removeClass(input, swalClasses.inputerror);
1934
+ }
1935
+ }
1936
+
1937
+ function getProgressSteps$1() {
1938
+ warnAboutDepreation('Swal.getProgressSteps()', "const swalInstance = Swal.fire({progressSteps: ['1', '2', '3']}); const progressSteps = swalInstance.params.progressSteps");
1939
+ var innerParams = privateProps.innerParams.get(this);
1940
+ return innerParams.progressSteps;
1941
+ }
1942
+ function setProgressSteps(progressSteps) {
1943
+ warnAboutDepreation('Swal.setProgressSteps()', 'Swal.update()');
1944
+ var innerParams = privateProps.innerParams.get(this);
1945
+
1946
+ var updatedParams = _extends({}, innerParams, {
1947
+ progressSteps: progressSteps
1948
+ });
1949
+
1950
+ renderProgressSteps(this, updatedParams);
1951
+ privateProps.innerParams.set(this, updatedParams);
1952
+ }
1953
+ function showProgressSteps() {
1954
+ var domCache = privateProps.domCache.get(this);
1955
+ show(domCache.progressSteps);
1956
+ }
1957
+ function hideProgressSteps() {
1958
+ var domCache = privateProps.domCache.get(this);
1959
+ hide(domCache.progressSteps);
1960
+ }
1961
+
1962
+ var Timer =
1963
+ /*#__PURE__*/
1964
+ function () {
1965
+ function Timer(callback, delay) {
1966
+ _classCallCheck(this, Timer);
1967
+
1968
+ this.callback = callback;
1969
+ this.remaining = delay;
1970
+ this.running = false;
1971
+ this.start();
1972
+ }
1973
+
1974
+ _createClass(Timer, [{
1975
+ key: "start",
1976
+ value: function start() {
1977
+ if (!this.running) {
1978
+ this.running = true;
1979
+ this.started = new Date();
1980
+ this.id = setTimeout(this.callback, this.remaining);
1981
+ }
1982
+
1983
+ return this.remaining;
1984
+ }
1985
+ }, {
1986
+ key: "stop",
1987
+ value: function stop() {
1988
+ if (this.running) {
1989
+ this.running = false;
1990
+ clearTimeout(this.id);
1991
+ this.remaining -= new Date() - this.started;
1992
+ }
1993
+
1994
+ return this.remaining;
1995
+ }
1996
+ }, {
1997
+ key: "increase",
1998
+ value: function increase(n) {
1999
+ var running = this.running;
2000
+
2001
+ if (running) {
2002
+ this.stop();
2003
+ }
2004
+
2005
+ this.remaining += n;
2006
+
2007
+ if (running) {
2008
+ this.start();
2009
+ }
2010
+
2011
+ return this.remaining;
2012
+ }
2013
+ }, {
2014
+ key: "getTimerLeft",
2015
+ value: function getTimerLeft() {
2016
+ if (this.running) {
2017
+ this.stop();
2018
+ this.start();
2019
+ }
2020
+
2021
+ return this.remaining;
2022
+ }
2023
+ }, {
2024
+ key: "isRunning",
2025
+ value: function isRunning() {
2026
+ return this.running;
2027
+ }
2028
+ }]);
2029
+
2030
+ return Timer;
2031
+ }();
2032
+
2033
+ var defaultInputValidators = {
2034
+ email: function email(string, validationMessage) {
2035
+ return /^[a-zA-Z0-9.+_-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9-]{2,24}$/.test(string) ? Promise.resolve() : Promise.resolve(validationMessage ? validationMessage : 'Invalid email address');
2036
+ },
2037
+ url: function url(string, validationMessage) {
2038
+ // taken from https://stackoverflow.com/a/3809435 with a small change from #1306
2039
+ return /^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\.[a-z]{2,63}\b([-a-zA-Z0-9@:%_+.~#?&/=]*)$/.test(string) ? Promise.resolve() : Promise.resolve(validationMessage ? validationMessage : 'Invalid URL');
2040
+ }
2041
+ };
2042
+
2043
+ /**
2044
+ * Set type, text and actions on popup
2045
+ *
2046
+ * @param params
2047
+ * @returns {boolean}
2048
+ */
2049
+
2050
+ function setParameters(params) {
2051
+ // Use default `inputValidator` for supported input types if not provided
2052
+ if (!params.inputValidator) {
2053
+ Object.keys(defaultInputValidators).forEach(function (key) {
2054
+ if (params.input === key) {
2055
+ params.inputValidator = defaultInputValidators[key];
2056
+ }
2057
+ });
2058
+ } // showLoaderOnConfirm && preConfirm
2059
+
2060
+
2061
+ if (params.showLoaderOnConfirm && !params.preConfirm) {
2062
+ warn('showLoaderOnConfirm is set to true, but preConfirm is not defined.\n' + 'showLoaderOnConfirm should be used together with preConfirm, see usage example:\n' + 'https://sweetalert2.github.io/#ajax-request');
2063
+ } // params.animation will be actually used in renderPopup.js
2064
+ // but in case when params.animation is a function, we need to call that function
2065
+ // before popup (re)initialization, so it'll be possible to check Swal.isVisible()
2066
+ // inside the params.animation function
2067
+
2068
+
2069
+ params.animation = callIfFunction(params.animation); // Determine if the custom target element is valid
2070
+
2071
+ if (!params.target || typeof params.target === 'string' && !document.querySelector(params.target) || typeof params.target !== 'string' && !params.target.appendChild) {
2072
+ warn('Target parameter is not valid, defaulting to "body"');
2073
+ params.target = 'body';
2074
+ } // Replace newlines with <br> in title
2075
+
2076
+
2077
+ if (typeof params.title === 'string') {
2078
+ params.title = params.title.split('\n').join('<br />');
2079
+ }
2080
+
2081
+ var oldPopup = getPopup();
2082
+ var targetElement = typeof params.target === 'string' ? document.querySelector(params.target) : params.target;
2083
+
2084
+ if (!oldPopup || // If the model target has changed, refresh the popup
2085
+ oldPopup && targetElement && oldPopup.parentNode !== targetElement.parentNode) {
2086
+ init(params);
2087
+ }
2088
+ }
2089
+
2090
+ function swalOpenAnimationFinished(popup, container) {
2091
+ popup.removeEventListener(animationEndEvent, swalOpenAnimationFinished);
2092
+ container.style.overflowY = 'auto';
2093
+ }
2094
+ /**
2095
+ * Open popup, add necessary classes and styles, fix scrollbar
2096
+ *
2097
+ * @param {Array} params
2098
+ */
2099
+
2100
+
2101
+ var openPopup = function openPopup(params) {
2102
+ var container = getContainer();
2103
+ var popup = getPopup();
2104
+
2105
+ if (params.onBeforeOpen !== null && typeof params.onBeforeOpen === 'function') {
2106
+ params.onBeforeOpen(popup);
2107
+ }
2108
+
2109
+ if (params.animation) {
2110
+ addClass(popup, swalClasses.show);
2111
+ addClass(container, swalClasses.fade);
2112
+ }
2113
+
2114
+ show(popup); // scrolling is 'hidden' until animation is done, after that 'auto'
2115
+
2116
+ if (animationEndEvent && hasCssAnimation(popup)) {
2117
+ container.style.overflowY = 'hidden';
2118
+ popup.addEventListener(animationEndEvent, swalOpenAnimationFinished.bind(null, popup, container));
2119
+ } else {
2120
+ container.style.overflowY = 'auto';
2121
+ }
2122
+
2123
+ addClass([document.documentElement, document.body, container], swalClasses.shown);
2124
+
2125
+ if (params.heightAuto && params.backdrop && !params.toast) {
2126
+ addClass([document.documentElement, document.body], swalClasses['height-auto']);
2127
+ }
2128
+
2129
+ if (isModal()) {
2130
+ if (params.scrollbarPadding) {
2131
+ fixScrollbar();
2132
+ }
2133
+
2134
+ iOSfix();
2135
+ IEfix();
2136
+ setAriaHidden(); // sweetalert2/issues/1247
2137
+
2138
+ setTimeout(function () {
2139
+ container.scrollTop = 0;
2140
+ });
2141
+ }
2142
+
2143
+ if (!isToast() && !globalState.previousActiveElement) {
2144
+ globalState.previousActiveElement = document.activeElement;
2145
+ }
2146
+
2147
+ if (params.onOpen !== null && typeof params.onOpen === 'function') {
2148
+ setTimeout(function () {
2149
+ params.onOpen(popup);
2150
+ });
2151
+ }
2152
+ };
2153
+
2154
+ var _this = undefined;
2155
+
2156
+ var handleInputOptions = function handleInputOptions(instance, params) {
2157
+ var content = getContent();
2158
+
2159
+ var processInputOptions = function processInputOptions(inputOptions) {
2160
+ return populateInputOptions[params.input](content, formatInputOptions(inputOptions), params);
2161
+ };
2162
+
2163
+ if (isPromise(params.inputOptions)) {
2164
+ showLoading();
2165
+ params.inputOptions.then(function (inputOptions) {
2166
+ instance.hideLoading();
2167
+ processInputOptions(inputOptions);
2168
+ });
2169
+ } else if (_typeof(params.inputOptions) === 'object') {
2170
+ processInputOptions(params.inputOptions);
2171
+ } else {
2172
+ error("Unexpected type of inputOptions! Expected object, Map or Promise, got ".concat(_typeof(params.inputOptions)));
2173
+ }
2174
+ };
2175
+ var handleInputValue = function handleInputValue(instance, params) {
2176
+ var input = instance.getInput();
2177
+ hide(input);
2178
+ params.inputValue.then(function (inputValue) {
2179
+ input.value = params.input === 'number' ? parseFloat(inputValue) || 0 : inputValue + '';
2180
+ show(input);
2181
+ input.focus();
2182
+ instance.hideLoading();
2183
+ })["catch"](function (err) {
2184
+ error('Error in inputValue promise: ' + err);
2185
+ input.value = '';
2186
+ show(input);
2187
+ input.focus();
2188
+
2189
+ _this.hideLoading();
2190
+ });
2191
+ };
2192
+ var populateInputOptions = {
2193
+ select: function select(content, inputOptions, params) {
2194
+ var select = getChildByClass(content, swalClasses.select);
2195
+ inputOptions.forEach(function (inputOption) {
2196
+ var optionValue = inputOption[0];
2197
+ var optionLabel = inputOption[1];
2198
+ var option = document.createElement('option');
2199
+ option.value = optionValue;
2200
+ option.innerHTML = optionLabel;
2201
+
2202
+ if (params.inputValue.toString() === optionValue.toString()) {
2203
+ option.selected = true;
2204
+ }
2205
+
2206
+ select.appendChild(option);
2207
+ });
2208
+ select.focus();
2209
+ },
2210
+ radio: function radio(content, inputOptions, params) {
2211
+ var radio = getChildByClass(content, swalClasses.radio);
2212
+ inputOptions.forEach(function (inputOption) {
2213
+ var radioValue = inputOption[0];
2214
+ var radioLabel = inputOption[1];
2215
+ var radioInput = document.createElement('input');
2216
+ var radioLabelElement = document.createElement('label');
2217
+ radioInput.type = 'radio';
2218
+ radioInput.name = swalClasses.radio;
2219
+ radioInput.value = radioValue;
2220
+
2221
+ if (params.inputValue.toString() === radioValue.toString()) {
2222
+ radioInput.checked = true;
2223
+ }
2224
+
2225
+ var label = document.createElement('span');
2226
+ label.innerHTML = radioLabel;
2227
+ label.className = swalClasses.label;
2228
+ radioLabelElement.appendChild(radioInput);
2229
+ radioLabelElement.appendChild(label);
2230
+ radio.appendChild(radioLabelElement);
2231
+ });
2232
+ var radios = radio.querySelectorAll('input');
2233
+
2234
+ if (radios.length) {
2235
+ radios[0].focus();
2236
+ }
2237
+ }
2238
+ /**
2239
+ * Converts `inputOptions` into an array of `[value, label]`s
2240
+ * @param inputOptions
2241
+ */
2242
+
2243
+ };
2244
+
2245
+ var formatInputOptions = function formatInputOptions(inputOptions) {
2246
+ var result = [];
2247
+
2248
+ if (typeof Map !== 'undefined' && inputOptions instanceof Map) {
2249
+ inputOptions.forEach(function (value, key) {
2250
+ result.push([key, value]);
2251
+ });
2252
+ } else {
2253
+ Object.keys(inputOptions).forEach(function (key) {
2254
+ result.push([key, inputOptions[key]]);
2255
+ });
2256
+ }
2257
+
2258
+ return result;
2259
+ };
2260
+
2261
+ function _main(userParams) {
2262
+ var _this = this;
2263
+
2264
+ showWarningsForParams(userParams);
2265
+
2266
+ var innerParams = _extends({}, defaultParams, userParams);
2267
+
2268
+ setParameters(innerParams);
2269
+ Object.freeze(innerParams); // clear the previous timer
2270
+
2271
+ if (globalState.timeout) {
2272
+ globalState.timeout.stop();
2273
+ delete globalState.timeout;
2274
+ } // clear the restore focus timeout
2275
+
2276
+
2277
+ clearTimeout(globalState.restoreFocusTimeout);
2278
+ var domCache = {
2279
+ popup: getPopup(),
2280
+ container: getContainer(),
2281
+ content: getContent(),
2282
+ actions: getActions(),
2283
+ confirmButton: getConfirmButton(),
2284
+ cancelButton: getCancelButton(),
2285
+ closeButton: getCloseButton(),
2286
+ validationMessage: getValidationMessage(),
2287
+ progressSteps: getProgressSteps()
2288
+ };
2289
+ privateProps.domCache.set(this, domCache);
2290
+ render(this, innerParams);
2291
+ privateProps.innerParams.set(this, innerParams);
2292
+ var constructor = this.constructor;
2293
+ return new Promise(function (resolve) {
2294
+ // functions to handle all closings/dismissals
2295
+ var succeedWith = function succeedWith(value) {
2296
+ _this.closePopup({
2297
+ value: value
2298
+ });
2299
+ };
2300
+
2301
+ var dismissWith = function dismissWith(dismiss) {
2302
+ _this.closePopup({
2303
+ dismiss: dismiss
2304
+ });
2305
+ };
2306
+
2307
+ privateMethods.swalPromiseResolve.set(_this, resolve); // Close on timer
2308
+
2309
+ if (innerParams.timer) {
2310
+ globalState.timeout = new Timer(function () {
2311
+ dismissWith('timer');
2312
+ delete globalState.timeout;
2313
+ }, innerParams.timer);
2314
+ } // Get the value of the popup input
2315
+
2316
+
2317
+ var getInputValue = function getInputValue() {
2318
+ var input = _this.getInput();
2319
+
2320
+ if (!input) {
2321
+ return null;
2322
+ }
2323
+
2324
+ switch (innerParams.input) {
2325
+ case 'checkbox':
2326
+ return input.checked ? 1 : 0;
2327
+
2328
+ case 'radio':
2329
+ return input.checked ? input.value : null;
2330
+
2331
+ case 'file':
2332
+ return input.files.length ? input.files[0] : null;
2333
+
2334
+ default:
2335
+ return innerParams.inputAutoTrim ? input.value.trim() : input.value;
2336
+ }
2337
+ }; // input autofocus
2338
+
2339
+
2340
+ if (innerParams.input) {
2341
+ setTimeout(function () {
2342
+ var input = _this.getInput();
2343
+
2344
+ if (input) {
2345
+ focusInput(input);
2346
+ }
2347
+ }, 0);
2348
+ }
2349
+
2350
+ var confirm = function confirm(value) {
2351
+ if (innerParams.showLoaderOnConfirm) {
2352
+ constructor.showLoading(); // TODO: make showLoading an *instance* method
2353
+ }
2354
+
2355
+ if (innerParams.preConfirm) {
2356
+ _this.resetValidationMessage();
2357
+
2358
+ var preConfirmPromise = Promise.resolve().then(function () {
2359
+ return innerParams.preConfirm(value, innerParams.validationMessage);
2360
+ });
2361
+ preConfirmPromise.then(function (preConfirmValue) {
2362
+ if (isVisible(domCache.validationMessage) || preConfirmValue === false) {
2363
+ _this.hideLoading();
2364
+ } else {
2365
+ succeedWith(typeof preConfirmValue === 'undefined' ? value : preConfirmValue);
2366
+ }
2367
+ });
2368
+ } else {
2369
+ succeedWith(value);
2370
+ }
2371
+ }; // Mouse interactions
2372
+
2373
+
2374
+ var onButtonEvent = function onButtonEvent(e) {
2375
+ var target = e.target;
2376
+ var confirmButton = domCache.confirmButton,
2377
+ cancelButton = domCache.cancelButton;
2378
+ var targetedConfirm = confirmButton && (confirmButton === target || confirmButton.contains(target));
2379
+ var targetedCancel = cancelButton && (cancelButton === target || cancelButton.contains(target));
2380
+
2381
+ switch (e.type) {
2382
+ case 'click':
2383
+ // Clicked 'confirm'
2384
+ if (targetedConfirm) {
2385
+ _this.disableButtons();
2386
+
2387
+ if (innerParams.input) {
2388
+ var inputValue = getInputValue();
2389
+
2390
+ if (innerParams.inputValidator) {
2391
+ _this.disableInput();
2392
+
2393
+ var validationPromise = Promise.resolve().then(function () {
2394
+ return innerParams.inputValidator(inputValue, innerParams.validationMessage);
2395
+ });
2396
+ validationPromise.then(function (validationMessage) {
2397
+ _this.enableButtons();
2398
+
2399
+ _this.enableInput();
2400
+
2401
+ if (validationMessage) {
2402
+ _this.showValidationMessage(validationMessage);
2403
+ } else {
2404
+ confirm(inputValue);
2405
+ }
2406
+ });
2407
+ } else if (!_this.getInput().checkValidity()) {
2408
+ _this.enableButtons();
2409
+
2410
+ _this.showValidationMessage(innerParams.validationMessage);
2411
+ } else {
2412
+ confirm(inputValue);
2413
+ }
2414
+ } else {
2415
+ confirm(true);
2416
+ } // Clicked 'cancel'
2417
+
2418
+ } else if (targetedCancel) {
2419
+ _this.disableButtons();
2420
+
2421
+ dismissWith(constructor.DismissReason.cancel);
2422
+ }
2423
+
2424
+ break;
2425
+
2426
+ default:
2427
+ }
2428
+ };
2429
+
2430
+ var buttons = domCache.popup.querySelectorAll('button');
2431
+
2432
+ for (var i = 0; i < buttons.length; i++) {
2433
+ buttons[i].onclick = onButtonEvent;
2434
+ buttons[i].onmouseover = onButtonEvent;
2435
+ buttons[i].onmouseout = onButtonEvent;
2436
+ buttons[i].onmousedown = onButtonEvent;
2437
+ } // Closing popup by close button
2438
+
2439
+
2440
+ domCache.closeButton.onclick = function () {
2441
+ dismissWith(constructor.DismissReason.close);
2442
+ };
2443
+
2444
+ if (innerParams.toast) {
2445
+ // Closing popup by internal click
2446
+ domCache.popup.onclick = function () {
2447
+ if (innerParams.showConfirmButton || innerParams.showCancelButton || innerParams.showCloseButton || innerParams.input) {
2448
+ return;
2449
+ }
2450
+
2451
+ dismissWith(constructor.DismissReason.close);
2452
+ };
2453
+ } else {
2454
+ var ignoreOutsideClick = false; // Ignore click events that had mousedown on the popup but mouseup on the container
2455
+ // This can happen when the user drags a slider
2456
+
2457
+ domCache.popup.onmousedown = function () {
2458
+ domCache.container.onmouseup = function (e) {
2459
+ domCache.container.onmouseup = undefined; // We only check if the mouseup target is the container because usually it doesn't
2460
+ // have any other direct children aside of the popup
2461
+
2462
+ if (e.target === domCache.container) {
2463
+ ignoreOutsideClick = true;
2464
+ }
2465
+ };
2466
+ }; // Ignore click events that had mousedown on the container but mouseup on the popup
2467
+
2468
+
2469
+ domCache.container.onmousedown = function () {
2470
+ domCache.popup.onmouseup = function (e) {
2471
+ domCache.popup.onmouseup = undefined; // We also need to check if the mouseup target is a child of the popup
2472
+
2473
+ if (e.target === domCache.popup || domCache.popup.contains(e.target)) {
2474
+ ignoreOutsideClick = true;
2475
+ }
2476
+ };
2477
+ };
2478
+
2479
+ domCache.container.onclick = function (e) {
2480
+ if (ignoreOutsideClick) {
2481
+ ignoreOutsideClick = false;
2482
+ return;
2483
+ }
2484
+
2485
+ if (e.target !== domCache.container) {
2486
+ return;
2487
+ }
2488
+
2489
+ if (callIfFunction(innerParams.allowOutsideClick)) {
2490
+ dismissWith(constructor.DismissReason.backdrop);
2491
+ }
2492
+ };
2493
+ } // Reverse buttons (Confirm on the right side)
2494
+
2495
+
2496
+ if (innerParams.reverseButtons) {
2497
+ domCache.confirmButton.parentNode.insertBefore(domCache.cancelButton, domCache.confirmButton);
2498
+ } else {
2499
+ domCache.confirmButton.parentNode.insertBefore(domCache.confirmButton, domCache.cancelButton);
2500
+ } // Focus handling
2501
+
2502
+
2503
+ var setFocus = function setFocus(index, increment) {
2504
+ var focusableElements = getFocusableElements(innerParams.focusCancel); // search for visible elements and select the next possible match
2505
+
2506
+ for (var _i = 0; _i < focusableElements.length; _i++) {
2507
+ index = index + increment; // rollover to first item
2508
+
2509
+ if (index === focusableElements.length) {
2510
+ index = 0; // go to last item
2511
+ } else if (index === -1) {
2512
+ index = focusableElements.length - 1;
2513
+ }
2514
+
2515
+ return focusableElements[index].focus();
2516
+ } // no visible focusable elements, focus the popup
2517
+
2518
+
2519
+ domCache.popup.focus();
2520
+ };
2521
+
2522
+ var keydownHandler = function keydownHandler(e, innerParams) {
2523
+ if (innerParams.stopKeydownPropagation) {
2524
+ e.stopPropagation();
2525
+ }
2526
+
2527
+ var arrowKeys = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Left', 'Right', 'Up', 'Down' // IE11
2528
+ ];
2529
+
2530
+ if (e.key === 'Enter' && !e.isComposing) {
2531
+ if (e.target && _this.getInput() && e.target.outerHTML === _this.getInput().outerHTML) {
2532
+ if (['textarea', 'file'].indexOf(innerParams.input) !== -1) {
2533
+ return; // do not submit
2534
+ }
2535
+
2536
+ constructor.clickConfirm();
2537
+ e.preventDefault();
2538
+ } // TAB
2539
+
2540
+ } else if (e.key === 'Tab') {
2541
+ var targetElement = e.target;
2542
+ var focusableElements = getFocusableElements(innerParams.focusCancel);
2543
+ var btnIndex = -1;
2544
+
2545
+ for (var _i2 = 0; _i2 < focusableElements.length; _i2++) {
2546
+ if (targetElement === focusableElements[_i2]) {
2547
+ btnIndex = _i2;
2548
+ break;
2549
+ }
2550
+ }
2551
+
2552
+ if (!e.shiftKey) {
2553
+ // Cycle to the next button
2554
+ setFocus(btnIndex, 1);
2555
+ } else {
2556
+ // Cycle to the prev button
2557
+ setFocus(btnIndex, -1);
2558
+ }
2559
+
2560
+ e.stopPropagation();
2561
+ e.preventDefault(); // ARROWS - switch focus between buttons
2562
+ } else if (arrowKeys.indexOf(e.key) !== -1) {
2563
+ // focus Cancel button if Confirm button is currently focused
2564
+ if (document.activeElement === domCache.confirmButton && isVisible(domCache.cancelButton)) {
2565
+ domCache.cancelButton.focus(); // and vice versa
2566
+ } else if (document.activeElement === domCache.cancelButton && isVisible(domCache.confirmButton)) {
2567
+ domCache.confirmButton.focus();
2568
+ } // ESC
2569
+
2570
+ } else if ((e.key === 'Escape' || e.key === 'Esc') && callIfFunction(innerParams.allowEscapeKey) === true) {
2571
+ e.preventDefault();
2572
+ dismissWith(constructor.DismissReason.esc);
2573
+ }
2574
+ };
2575
+
2576
+ if (globalState.keydownTarget && globalState.keydownHandlerAdded) {
2577
+ globalState.keydownTarget.removeEventListener('keydown', globalState.keydownHandler, {
2578
+ capture: globalState.keydownListenerCapture
2579
+ });
2580
+ globalState.keydownHandlerAdded = false;
2581
+ }
2582
+
2583
+ if (!innerParams.toast) {
2584
+ globalState.keydownHandler = function (e) {
2585
+ return keydownHandler(e, innerParams);
2586
+ };
2587
+
2588
+ globalState.keydownTarget = innerParams.keydownListenerCapture ? window : domCache.popup;
2589
+ globalState.keydownListenerCapture = innerParams.keydownListenerCapture;
2590
+ globalState.keydownTarget.addEventListener('keydown', globalState.keydownHandler, {
2591
+ capture: globalState.keydownListenerCapture
2592
+ });
2593
+ globalState.keydownHandlerAdded = true;
2594
+ }
2595
+
2596
+ _this.enableButtons();
2597
+
2598
+ _this.hideLoading();
2599
+
2600
+ _this.resetValidationMessage();
2601
+
2602
+ if (innerParams.toast && (innerParams.input || innerParams.footer || innerParams.showCloseButton)) {
2603
+ addClass(document.body, swalClasses['toast-column']);
2604
+ } else {
2605
+ removeClass(document.body, swalClasses['toast-column']);
2606
+ } // inputOptions, inputValue
2607
+
2608
+
2609
+ if (innerParams.input === 'select' || innerParams.input === 'radio') {
2610
+ handleInputOptions(_this, innerParams);
2611
+ } else if (['text', 'email', 'number', 'tel', 'textarea'].indexOf(innerParams.input) !== -1 && isPromise(innerParams.inputValue)) {
2612
+ handleInputValue(_this, innerParams);
2613
+ }
2614
+
2615
+ openPopup(innerParams);
2616
+
2617
+ if (!innerParams.toast) {
2618
+ if (!callIfFunction(innerParams.allowEnterKey)) {
2619
+ if (document.activeElement && typeof document.activeElement.blur === 'function') {
2620
+ document.activeElement.blur();
2621
+ }
2622
+ } else if (innerParams.focusCancel && isVisible(domCache.cancelButton)) {
2623
+ domCache.cancelButton.focus();
2624
+ } else if (innerParams.focusConfirm && isVisible(domCache.confirmButton)) {
2625
+ domCache.confirmButton.focus();
2626
+ } else {
2627
+ setFocus(-1, 1);
2628
+ }
2629
+ } // fix scroll
2630
+
2631
+
2632
+ domCache.container.scrollTop = 0;
2633
+ });
2634
+ }
2635
+
2636
+ /**
2637
+ * Updates popup parameters.
2638
+ */
2639
+
2640
+ function update(params) {
2641
+ var validUpdatableParams = {}; // assign valid params from `params` to `defaults`
2642
+
2643
+ Object.keys(params).forEach(function (param) {
2644
+ if (Swal.isUpdatableParameter(param)) {
2645
+ validUpdatableParams[param] = params[param];
2646
+ } else {
2647
+ warn("Invalid parameter to update: \"".concat(param, "\". Updatable params are listed here: https://github.com/sweetalert2/sweetalert2/blob/master/src/utils/params.js"));
2648
+ }
2649
+ });
2650
+ var innerParams = privateProps.innerParams.get(this);
2651
+
2652
+ var updatedParams = _extends({}, innerParams, validUpdatableParams);
2653
+
2654
+ render(this, updatedParams);
2655
+ privateProps.innerParams.set(this, updatedParams);
2656
+ Object.defineProperties(this, {
2657
+ params: {
2658
+ value: _extends({}, this.params, params),
2659
+ writable: false,
2660
+ enumerable: true
2661
+ }
2662
+ });
2663
+ }
2664
+
2665
+
2666
+
2667
+ var instanceMethods = Object.freeze({
2668
+ hideLoading: hideLoading,
2669
+ disableLoading: hideLoading,
2670
+ getInput: getInput$1,
2671
+ close: close,
2672
+ closePopup: close,
2673
+ closeModal: close,
2674
+ closeToast: close,
2675
+ enableButtons: enableButtons,
2676
+ disableButtons: disableButtons,
2677
+ enableConfirmButton: enableConfirmButton,
2678
+ disableConfirmButton: disableConfirmButton,
2679
+ enableInput: enableInput,
2680
+ disableInput: disableInput,
2681
+ showValidationMessage: showValidationMessage,
2682
+ resetValidationMessage: resetValidationMessage$1,
2683
+ getProgressSteps: getProgressSteps$1,
2684
+ setProgressSteps: setProgressSteps,
2685
+ showProgressSteps: showProgressSteps,
2686
+ hideProgressSteps: hideProgressSteps,
2687
+ _main: _main,
2688
+ update: update
2689
+ });
2690
+
2691
+ var currentInstance; // SweetAlert constructor
2692
+
2693
+ function SweetAlert() {
2694
+ // Prevent run in Node env
2695
+
2696
+ /* istanbul ignore if */
2697
+ if (typeof window === 'undefined') {
2698
+ return;
2699
+ } // Check for the existence of Promise
2700
+
2701
+ /* istanbul ignore if */
2702
+
2703
+
2704
+ if (typeof Promise === 'undefined') {
2705
+ error('This package requires a Promise library, please include a shim to enable it in this browser (See: https://github.com/sweetalert2/sweetalert2/wiki/Migration-from-SweetAlert-to-SweetAlert2#1-ie-support)');
2706
+ }
2707
+
2708
+ currentInstance = this;
2709
+
2710
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
2711
+ args[_key] = arguments[_key];
2712
+ }
2713
+
2714
+ var outerParams = Object.freeze(this.constructor.argsToParams(args));
2715
+ Object.defineProperties(this, {
2716
+ params: {
2717
+ value: outerParams,
2718
+ writable: false,
2719
+ enumerable: true,
2720
+ configurable: true
2721
+ }
2722
+ });
2723
+
2724
+ var promise = this._main(this.params);
2725
+
2726
+ privateProps.promise.set(this, promise);
2727
+ } // `catch` cannot be the name of a module export, so we define our thenable methods here instead
2728
+
2729
+
2730
+ SweetAlert.prototype.then = function (onFulfilled) {
2731
+ var promise = privateProps.promise.get(this);
2732
+ return promise.then(onFulfilled);
2733
+ };
2734
+
2735
+ SweetAlert.prototype["finally"] = function (onFinally) {
2736
+ var promise = privateProps.promise.get(this);
2737
+ return promise["finally"](onFinally);
2738
+ }; // Assign instance methods from src/instanceMethods/*.js to prototype
2739
+
2740
+
2741
+ _extends(SweetAlert.prototype, instanceMethods); // Assign static methods from src/staticMethods/*.js to constructor
2742
+
2743
+
2744
+ _extends(SweetAlert, staticMethods); // Proxy to instance methods to constructor, for now, for backwards compatibility
2745
+
2746
+
2747
+ Object.keys(instanceMethods).forEach(function (key) {
2748
+ SweetAlert[key] = function () {
2749
+ if (currentInstance) {
2750
+ var _currentInstance;
2751
+
2752
+ return (_currentInstance = currentInstance)[key].apply(_currentInstance, arguments);
2753
+ }
2754
+ };
2755
+ });
2756
+ SweetAlert.DismissReason = DismissReason;
2757
+ SweetAlert.version = '8.11.1';
2758
+
2759
+ var Swal = SweetAlert;
2760
+ Swal["default"] = Swal;
2761
+
2762
+ return Swal;
2763
+
2764
+ })));
2765
+ if (typeof window !== 'undefined' && window.Sweetalert2){ window.swal = window.sweetAlert = window.Swal = window.SweetAlert = window.Sweetalert2}
includes/feedback/class-ig-deactivation-survey.php DELETED
@@ -1,331 +0,0 @@
1
- <?php
2
-
3
- defined( 'ABSPATH' ) || exit;
4
-
5
- if ( ! class_exists( 'IG_Feedback_V_1_0_0', false ) ) {
6
- include_once dirname( __FILE__ ) . '/class-ig-feedback-v-1-0-0.php';
7
- }
8
-
9
- if ( ! class_exists( 'IG_Deactivation_Survey' ) ) {
10
- /**
11
- * Icegram Deactivation Survey.
12
- *
13
- * This prompts the user for more details when they deactivate the plugin.
14
- *
15
- * @version 1.0.0
16
- * @package Icegram
17
- * @author Malay Ladu
18
- * @license GPL-2.0+
19
- * @copyright Copyright (c) 2019
20
- */
21
- class IG_Deactivation_Survey extends IG_Feedback_V_1_0_0 {
22
-
23
- public function __construct( $name = '', $plugin = '', $plugin_abbr = 'ig_fb' ) {
24
- parent::__construct($name, $plugin, $plugin_abbr);
25
-
26
- // Don't run deactivation survey on dev sites.
27
- if ( ! $this->can_show_feedback_widget()) {
28
- return;
29
- }
30
-
31
- add_action( 'admin_print_scripts', array( $this, 'js' ), 20 );
32
- add_action( 'admin_print_scripts', array( $this, 'css' ) );
33
- add_action( 'admin_footer', array( $this, 'modal' ) );
34
- }
35
-
36
- /**
37
- * Survey javascript.
38
- *
39
- * @since 1.0.0
40
- */
41
- public function js() {
42
-
43
- if ( ! $this->is_plugin_page() ) {
44
- return;
45
- }
46
- ?>
47
- <script type="text/javascript">
48
- jQuery(function ($) {
49
- var $deactivateLink = $('#the-list').find('[data-slug="<?php echo $this->plugin; ?>"] span.deactivate a'),
50
- $overlay = $('#ig-deactivate-survey-<?php echo $this->plugin; ?>'),
51
- $form = $overlay.find('form'),
52
- formOpen = false;
53
- // Plugin listing table deactivate link.
54
- $deactivateLink.on('click', function (event) {
55
- event.preventDefault();
56
- $overlay.css('display', 'table');
57
- formOpen = true;
58
- $form.find('.ig-deactivate-survey-option:first-of-type input[type=radio]').focus();
59
- });
60
- // Survey radio option selected.
61
- $form.on('change', 'input[type=radio]', function (event) {
62
- event.preventDefault();
63
- $form.find('input[type=text], .error').hide();
64
- $form.find('.ig-deactivate-survey-option').removeClass('selected');
65
- $(this).closest('.ig-deactivate-survey-option').addClass('selected').find('input[type=text]').show();
66
- });
67
- // Survey Skip & Deactivate.
68
- $form.on('click', '.ig-deactivate-survey-deactivate', function (event) {
69
- event.preventDefault();
70
- location.href = $deactivateLink.attr('href');
71
- });
72
- // Survey submit.
73
- $form.submit(function (event) {
74
- event.preventDefault();
75
- if (!$form.find('input[type=radio]:checked').val()) {
76
- $form.find('.ig-deactivate-survey-footer').prepend('<span class="error"><?php echo esc_js( __( 'Please select an option', 'email-subscribers' ) ); ?></span>');
77
- return;
78
- }
79
-
80
- var data = {
81
- action: '<?php echo $this->ajax_action; ?>',
82
- feedback: [{
83
- type: 'radio',
84
- slug: 'why-are-ypu-deactivating-email-subscribers',
85
- title: 'Why are you deactivating Email Subscribers',
86
- value: $form.find('.selected input[type=radio]').attr('data-option-slug'),
87
- details: $form.find('.selected input[type=text]').val()
88
- }],
89
-
90
- event: 'esfree.plugin.deactivation',
91
- };
92
-
93
- var submitSurvey = $.post(ajaxurl, data);
94
- submitSurvey.always(function () {
95
- location.href = $deactivateLink.attr('href');
96
- });
97
- });
98
- // Exit key closes survey when open.
99
- $(document).keyup(function (event) {
100
- if (27 === event.keyCode && formOpen) {
101
- $overlay.hide();
102
- formOpen = false;
103
- $deactivateLink.focus();
104
- }
105
- });
106
- });
107
- </script>
108
- <?php
109
- }
110
-
111
- /**
112
- * Survey CSS.
113
- *
114
- * @since 1.0.0
115
- */
116
- public function css() {
117
-
118
- if ( ! $this->is_plugin_page() ) {
119
- return;
120
- }
121
- ?>
122
- <style type="text/css">
123
- .ig-deactivate-survey-modal {
124
- display: none;
125
- table-layout: fixed;
126
- position: fixed;
127
- z-index: 9999;
128
- width: 100%;
129
- height: 100%;
130
- text-align: center;
131
- font-size: 14px;
132
- top: 0;
133
- left: 0;
134
- background: rgba(0, 0, 0, 0.8);
135
- }
136
-
137
- .ig-deactivate-survey-wrap {
138
- display: table-cell;
139
- vertical-align: middle;
140
- }
141
-
142
- .ig-deactivate-survey {
143
- background-color: #fff;
144
- max-width: 550px;
145
- margin: 0 auto;
146
- padding: 30px;
147
- text-align: left;
148
- }
149
-
150
- .ig-deactivate-survey .error {
151
- display: block;
152
- color: red;
153
- margin: 0 0 10px 0;
154
- }
155
-
156
- .ig-deactivate-survey-title {
157
- display: block;
158
- font-size: 18px;
159
- font-weight: 700;
160
- text-transform: uppercase;
161
- border-bottom: 1px solid #ddd;
162
- padding: 0 0 18px 0;
163
- margin: 0 0 18px 0;
164
- }
165
-
166
- .ig-deactivate-survey-title span {
167
- color: #999;
168
- margin-right: 10px;
169
- }
170
-
171
- .ig-deactivate-survey-desc {
172
- display: block;
173
- font-weight: 600;
174
- margin: 0 0 18px 0;
175
- }
176
-
177
- .ig-deactivate-survey-option {
178
- margin: 0 0 10px 0;
179
- }
180
-
181
- .ig-deactivate-survey-option-input {
182
- margin-right: 10px !important;
183
- }
184
-
185
- .ig-deactivate-survey-option-details {
186
- display: none;
187
- width: 90%;
188
- margin: 10px 0 0 30px;
189
- }
190
-
191
- .ig-deactivate-survey-footer {
192
- margin-top: 18px;
193
- }
194
-
195
- .ig-deactivate-survey-deactivate {
196
- float: right;
197
- font-size: 13px;
198
- color: #ccc;
199
- text-decoration: none;
200
- padding-top: 7px;
201
- }
202
- </style>
203
- <?php
204
- }
205
-
206
- /**
207
- * Survey modal.
208
- *
209
- * @since 1.0.0
210
- */
211
- public function modal() {
212
-
213
- if ( ! $this->is_plugin_page() ) {
214
- return;
215
- }
216
-
217
- $options = array(
218
- 1 => array(
219
- 'title' => esc_html__( 'I no longer need the plugin', 'email-subscribers' ),
220
- 'slug' => 'i-no-longer-need-the-plugin'
221
- ),
222
- 2 => array(
223
- 'title' => esc_html__( 'I\'m switching to a different plugin', 'email-subscribers' ),
224
- 'slug' => 'i-am-switching-to-a-different-plugin',
225
- 'details' => esc_html__( 'Please share which plugin', 'email-subscribers' ),
226
- ),
227
- 3 => array(
228
- 'title' => esc_html__( 'I couldn\'t get the plugin to work', 'email-subscribers' ),
229
- 'slug' => 'i-could-not-get-the-plugin-to-work'
230
- ),
231
- 4 => array(
232
- 'title' => esc_html__( 'It\'s a temporary deactivation', 'email-subscribers' ),
233
- 'slug' => 'it-is-a-temporary-deactivation'
234
- ),
235
- 5 => array(
236
- 'title' => esc_html__( 'Other', 'email-subscribers' ),
237
- 'slug' => 'other',
238
- 'details' => esc_html__( 'Please share the reason', 'email-subscribers' ),
239
- ),
240
- );
241
- ?>
242
- <div class="ig-deactivate-survey-modal" id="ig-deactivate-survey-<?php echo $this->plugin; ?>">
243
- <div class="ig-deactivate-survey-wrap">
244
- <form class="ig-deactivate-survey" method="post">
245
- <span class="ig-deactivate-survey-title"><span class="dashicons dashicons-testimonial"></span><?php echo ' ' . esc_html__( 'Quick Feedback', 'email-subscribers' ); ?></span>
246
- <span class="ig-deactivate-survey-desc"><?php echo sprintf( esc_html__( 'If you have a moment, please share why you are deactivating %s:', 'email-subscribers' ), $this->name ); ?></span>
247
- <div class="ig-deactivate-survey-options">
248
- <?php foreach ( $options as $id => $option ) : ?>
249
- <div class="ig-deactivate-survey-option">
250
- <label for="ig-deactivate-survey-option-<?php echo $this->plugin; ?>-<?php echo $id; ?>" class="ig-deactivate-survey-option-label">
251
- <input id="ig-deactivate-survey-option-<?php echo $this->plugin; ?>-<?php echo $id; ?>" class="ig-deactivate-survey-option-input" type="radio" name="code" value="<?php echo $id; ?>" data-option-slug="<?php echo $option['slug']; ?>" />
252
- <span class="ig-deactivate-survey-option-reason"><?php echo $option['title']; ?></span>
253
- </label>
254
- <?php if ( ! empty( $option['details'] ) ) : ?>
255
- <input class="ig-deactivate-survey-option-details" type="text" placeholder="<?php echo $option['details']; ?>"/>
256
- <?php endif; ?>
257
- </div>
258
- <?php endforeach; ?>
259
- </div>
260
- <div class="ig-deactivate-survey-footer">
261
- <button type="submit" class="ig-deactivate-survey-submit button button-primary button-large"><?php echo sprintf( esc_html__( 'Submit %s Deactivate', 'email-subscribers' ), '&amp;' ); ?></button>
262
- <a href="#" class="ig-deactivate-survey-deactivate"><?php echo sprintf( esc_html__( 'Skip %s Deactivate', 'email-subscribers' ), '&amp;' ); ?></a>
263
- </div>
264
- </form>
265
- </div>
266
- </div>
267
- <?php
268
- }
269
-
270
- /**
271
- * Is plugin in development mode?
272
- * @return bool
273
- */
274
- public function is_dev_mode() {
275
-
276
- if ( defined( 'IG_ES_DEV_MODE' ) && IG_ES_DEV_MODE ) {
277
- return true;
278
- }
279
-
280
- return false;
281
- }
282
-
283
- /**
284
- * Can we show feedback widget in this environment
285
- *
286
- * @return bool
287
- */
288
- public function can_show_feedback_widget() {
289
-
290
- // Is development mode? Enable it.
291
- if($this->is_dev_mode()) {
292
- return true;
293
- }
294
-
295
- // Don't show on dev setup if dev mode is off.
296
- if($this->is_dev_url()) {
297
- return false;
298
- }
299
-
300
- return true;
301
- }
302
-
303
- /**
304
- * Checks if current admin screen is the plugins page.
305
- *
306
- * @return bool
307
- * @since 1.0.0
308
- */
309
- public function is_plugin_page() {
310
-
311
- $screen = function_exists( 'get_current_screen' ) ? get_current_screen() : false;
312
- if ( empty( $screen ) ) {
313
- return false;
314
- }
315
-
316
- return ( ! empty( $screen->id ) && in_array( $screen->id, array( 'plugins', 'plugins-network' ), true ) );
317
- }
318
-
319
- /**
320
- * Get additional plugin specific information
321
- */
322
- public function get_additional_info() {
323
- $additional_info = array();
324
-
325
- $additional_info['ig_es_version'] = ES_PLUGIN_VERSION;
326
-
327
- return $additional_info;
328
- }
329
-
330
- }
331
- } // End if().
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/feedback/class-ig-feedback-v-1-0-0.php DELETED
@@ -1,212 +0,0 @@
1
- <?php
2
-
3
- defined( 'ABSPATH' ) || exit;
4
-
5
- if ( ! class_exists( 'IG_Feedback_V_1_0_0' ) ) {
6
- /**
7
- * Icegram Deactivation Survey.
8
- *
9
- * This prompts the user for more details when they deactivate the plugin.
10
- *
11
- * @version 1.0
12
- * @package Icegram
13
- * @author Malay Ladu
14
- * @license GPL-2.0+
15
- * @copyright Copyright (c) 2019
16
- */
17
- class IG_Feedback_V_1_0_0 {
18
-
19
- /**
20
- * The API URL where we will send feedback data.
21
- *
22
- * @since 1.0.0
23
- * @var string
24
- */
25
- public $api_url = 'https://api.icegram.com/store/feedback/'; // Production
26
-
27
- /**
28
- * Name for this plugin.
29
- *
30
- * @since 1.0.0
31
- * @var string
32
- */
33
- public $name;
34
-
35
- /**
36
- * Unique slug for this plugin.
37
- *
38
- * @since 1.0.0
39
- * @var string
40
- */
41
- public $plugin;
42
-
43
- /**
44
- * Ajax action where feedback data will post
45
- *
46
- * @since 1.0.0
47
- * @var string
48
- */
49
- public $ajax_action;
50
-
51
- /**
52
- * Plugin Abbreviation
53
- *
54
- * @since 1.0.0
55
- * @var string
56
- */
57
- public $plugin_abbr;
58
-
59
- /**
60
- * Primary class constructor.
61
- *
62
- * @param string $name Plugin name.
63
- * @param string $plugin Plugin slug.
64
- *
65
- * @since 1.0.0
66
- */
67
- public function __construct( $name = '', $plugin = '', $plugin_abbr = 'ig_fb' ) {
68
- $this->name = $name;
69
- $this->plugin = $plugin;
70
- $this->plugin_abbr = $plugin_abbr;
71
- $this->ajax_action = 'ig-submit-feedback';
72
-
73
- add_action( 'wp_ajax_' . $this->ajax_action, array( $this, 'submit_feedback' ) );
74
- }
75
-
76
- /**
77
- * It's a default constant for Feedback.
78
- *
79
- * @return bool
80
- */
81
- public function is_dev_mode() {
82
-
83
- if ( defined( 'IG_FEEDBACK_DEV_MODE' ) && IG_FEEDBACK_DEV_MODE ) {
84
- return true;
85
- }
86
-
87
- return false;
88
- }
89
-
90
- /**
91
- * Get API Url. It's a different for dev & production mode
92
- *
93
- * @return string
94
- */
95
- public function get_api_url() {
96
-
97
- if ( $this->is_dev_mode() ) {
98
- $this->api_url = 'http://192.168.0.130:9094/store/feedback/'; // Malay: Development
99
- }
100
-
101
- return $this->api_url;
102
- }
103
-
104
- /**
105
- * Checks if current site is a development one.
106
- *
107
- * @return bool
108
- * @since 1.2.0
109
- */
110
- public function is_dev_url() {
111
-
112
- $url = network_site_url( '/' );
113
- $is_local_url = false;
114
-
115
- // Trim it up
116
- $url = strtolower( trim( $url ) );
117
-
118
- // Need to get the host...so let's add the scheme so we can use parse_url
119
- if ( false === strpos( $url, 'http://' ) && false === strpos( $url, 'https://' ) ) {
120
- $url = 'http://' . $url;
121
- }
122
- $url_parts = parse_url( $url );
123
- $host = ! empty( $url_parts['host'] ) ? $url_parts['host'] : false;
124
- if ( ! empty( $url ) && ! empty( $host ) ) {
125
- if ( false !== ip2long( $host ) ) {
126
- if ( ! filter_var( $host, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) ) {
127
- $is_local_url = true;
128
- }
129
- } elseif ( 'localhost' === $host ) {
130
- $is_local_url = true;
131
- }
132
-
133
- $tlds_to_check = array( '.dev', '.local', ':8888' );
134
- foreach ( $tlds_to_check as $tld ) {
135
- if ( false !== strpos( $host, $tld ) ) {
136
- $is_local_url = true;
137
- continue;
138
- }
139
-
140
- }
141
- if ( substr_count( $host, '.' ) > 1 ) {
142
- $subdomains_to_check = array( 'dev.', '*.staging.', 'beta.', 'test.' );
143
- foreach ( $subdomains_to_check as $subdomain ) {
144
- $subdomain = str_replace( '.', '(.)', $subdomain );
145
- $subdomain = str_replace( array( '*', '(.)' ), '(.*)', $subdomain );
146
- if ( preg_match( '/^(' . $subdomain . ')/', $host ) ) {
147
- $is_local_url = true;
148
- continue;
149
- }
150
- }
151
- }
152
- }
153
-
154
- return $is_local_url;
155
- }
156
-
157
- /**
158
- * Collect Meta information
159
- *
160
- * @return array|mixed|void
161
- */
162
- public function get_additional_info() {
163
- return array();
164
- }
165
-
166
- /**
167
- * Hook to ajax_action
168
- *
169
- * Send feedback to server
170
- */
171
- function submit_feedback() {
172
-
173
- $data = ! empty( $_POST ) ? $_POST : array();
174
-
175
- $data['site'] = esc_url( home_url() );
176
-
177
- $meta_info = array(
178
- 'plugin' => sanitize_key( $this->plugin ),
179
- 'locale' => get_locale(),
180
- 'wp_version' => get_bloginfo( 'version' )
181
- );
182
-
183
- $additional_info = $this->get_additional_info(); // Get Additional meta information
184
-
185
- if ( is_array( $meta_info ) && count( $meta_info ) > 0 ) {
186
- $meta_info = $meta_info + $additional_info;
187
- }
188
-
189
- $data['meta'] = $meta_info;
190
-
191
- $args = array(
192
- 'timeout' => 15,
193
- 'sslverify' => false,
194
- 'body' => $data,
195
- 'blocking' => false
196
- );
197
-
198
- $response = wp_remote_post( $this->get_api_url(), $args );
199
-
200
- $result['status'] = 'success';
201
- if ( $response instanceof WP_Error ) {
202
- $error_message = $response->get_error_message();
203
- $result['status'] = 'error';
204
- $result['message'] = $error_message;
205
- }
206
-
207
- die( json_encode( $result ) );
208
-
209
- }
210
-
211
- }
212
- } // End if().
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/feedback/class-ig-feedback-v-1-0-1.php ADDED
@@ -0,0 +1,858 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * IG Feedback
4
+ *
5
+ * The IG Feedback class adds functionality to get quick interactive feedback from users.
6
+ * There are different types of feedabck widget like Stars, Emoji, Thubms Up/ Down, Number etc.
7
+ *
8
+ * @class IG_Feedback
9
+ * @package feedback
10
+ * @copyright Copyright (c) 2019, Icegram
11
+ * @license https://opensource.org/licenses/gpl-license GNU Public License
12
+ * @since 1.0.0
13
+ */
14
+
15
+ defined( 'ABSPATH' ) || exit;
16
+
17
+ if ( ! class_exists( 'IG_Feedback_V_1_0_1' ) ) {
18
+ /**
19
+ * Icegram Deactivation Survey.
20
+ *
21
+ * This prompts the user for more details when they deactivate the plugin.
22
+ *
23
+ * @version 1.0
24
+ * @package Icegram
25
+ * @author Malay Ladu
26
+ * @license GPL-2.0+
27
+ * @copyright Copyright (c) 2019
28
+ */
29
+ class IG_Feedback_V_1_0_1 {
30
+
31
+ /**
32
+ * The API URL where we will send feedback data.
33
+ *
34
+ * @since 1.0.0
35
+ * @var string
36
+ */
37
+ public $api_url = 'https://api.icegram.com/store/feedback/'; // Production
38
+
39
+ /**
40
+ * Name for this plugin.
41
+ *
42
+ * @since 1.0.0
43
+ * @var string
44
+ */
45
+ public $name;
46
+
47
+ /**
48
+ * Unique slug for this plugin.
49
+ *
50
+ * @since 1.0.0
51
+ * @var string
52
+ */
53
+ public $plugin;
54
+
55
+ /**
56
+ * Unique slug for this plugin.
57
+ *
58
+ * @since 1.0.0
59
+ * @var string
60
+ */
61
+ public $ajax_action;
62
+
63
+ /**
64
+ * Plugin Abbreviation
65
+ *
66
+ * @since 1.0.0
67
+ * @var string
68
+ */
69
+ public $plugin_abbr;
70
+
71
+ /**
72
+ * Enable/Disable Dev Mode
73
+ * @var bool
74
+ */
75
+ public $is_dev_mode = true;
76
+
77
+ /**
78
+ * Set feedback event
79
+ *
80
+ * @var string
81
+ */
82
+ public $event_prefix;
83
+
84
+ /**
85
+ *
86
+ */
87
+ public $footer = '<span class="ig-powered-by">Made With&nbsp;💜&nbsp;by&nbsp;<a href="https://www.icegram.com/" target="_blank">Icegram</a></span>';
88
+
89
+ /**
90
+ * Primary class constructor.
91
+ *
92
+ * @param string $name Plugin name.
93
+ * @param string $plugin Plugin slug.
94
+ *
95
+ * @since 1.0.0
96
+ */
97
+ public function __construct( $name = '', $plugin = '', $plugin_abbr = 'ig_fb', $event_prefix = 'igfb.', $is_dev_mode = false ) {
98
+
99
+ $this->name = $name;
100
+ $this->plugin = $plugin;
101
+ $this->plugin_abbr = $plugin_abbr;
102
+ $this->event_prefix = $event_prefix;
103
+ $this->ajax_action = $this->plugin_abbr . '_submit-feedback';
104
+ $this->is_dev_mode = $is_dev_mode;
105
+
106
+ // Don't run deactivation survey on dev sites.
107
+ if ( ! $this->can_show_feedback_widget() ) {
108
+ return;
109
+ }
110
+
111
+ add_action( 'wp_ajax_' . $this->ajax_action, array( $this, 'submit_feedback' ) );
112
+
113
+ add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_styles' ) );
114
+ add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
115
+ }
116
+
117
+ public function render_deactivate_feedback() {
118
+ add_action( 'admin_print_scripts', array( $this, 'js' ), 20 );
119
+ add_action( 'admin_print_scripts', array( $this, 'css' ) );
120
+ add_action( 'admin_footer', array( $this, 'modal' ) );
121
+ }
122
+
123
+ /**
124
+ * Load Javascripts
125
+ *
126
+ * @since 1.0.1
127
+ */
128
+ public function enqueue_scripts() {
129
+ wp_enqueue_script( 'sweetalert', plugin_dir_url( __FILE__ ) . 'assets/js/sweetalert2.js', array( 'jquery' ) );
130
+ }
131
+
132
+ /**
133
+ * Load Styles
134
+ *
135
+ * @since 1.0.1
136
+ */
137
+ public function enqueue_styles() {
138
+ wp_register_style( 'sweetalert', plugin_dir_url( __FILE__ ) . 'assets/css/sweetalert2.css' );
139
+ wp_enqueue_style( 'sweetalert' );
140
+
141
+ wp_register_style( 'animate', plugin_dir_url( __FILE__ ) . 'assets/css/animate.min.css' );
142
+ wp_enqueue_style( 'animate' );
143
+
144
+ wp_register_style( 'ig-feedback-star-rating', plugin_dir_url( __FILE__ ) . 'assets/css/star-rating.css' );
145
+ wp_enqueue_style( 'ig-feedback-star-rating' );
146
+
147
+ wp_register_style( 'ig-feedback-emoji', plugin_dir_url( __FILE__ ) . 'assets/css/emoji.css' );
148
+ wp_enqueue_style( 'ig-feedback-emoji' );
149
+ }
150
+
151
+ public function render_widget( $params = array() ) {
152
+
153
+ $default_params = array(
154
+ 'event' => 'feedback',
155
+ 'title' => 'How do you rate ' . $this->plugin,
156
+ 'position' => 'top-end',
157
+ 'width' => 300,
158
+ 'set_transient' => true,
159
+ 'allowOutsideClick' => false,
160
+ 'allowEscapeKey' => true,
161
+ 'showCloseButton' => true
162
+ );
163
+
164
+ $params = wp_parse_args( $params, $default_params );
165
+
166
+ $title = $params['title'];
167
+ $slug = sanitize_title( $title );
168
+ $event = $this->event_prefix . $params['event'];
169
+ $html = ! empty( $params['html'] ) ? $params['html'] : '';
170
+
171
+ ?>
172
+
173
+ <script>
174
+
175
+ function doSend(rating, details) {
176
+
177
+ var data = {
178
+ action: '<?php echo $this->ajax_action; ?>',
179
+ feedback: {
180
+ type: '<?php echo $params['type']; ?>',
181
+ slug: '<?php echo $slug; ?>',
182
+ title: '<?php echo esc_js($title); ?>',
183
+ value: rating,
184
+ details: details
185
+ },
186
+
187
+ event: '<?php echo $event; ?>',
188
+
189
+ // Add additional information
190
+ misc: {
191
+ plugin: '<?php echo $this->plugin; ?>',
192
+ plugin_abbr: '<?php echo $this->plugin_abbr; ?>',
193
+ is_dev_mode: '<?php echo $this->is_dev_mode; ?>',
194
+ set_transient: '<?php echo $params['set_transient']; ?>'
195
+ //system_info: enable_system_info
196
+ }
197
+ };
198
+
199
+ return jQuery.post(ajaxurl, data);
200
+ }
201
+
202
+ Swal.mixin({
203
+ footer: '<?php echo $this->footer; ?>',
204
+ position: '<?php echo $params['position']; ?>',
205
+ width: <?php echo $params['width']; ?>,
206
+ animation: false,
207
+ focusConfirm: false,
208
+ allowEscapeKey: '<?php echo $params['allowEscapeKey']; ?>',
209
+ showCloseButton: '<?php echo $params['showCloseButton']; ?>',
210
+ allowOutsideClick: '<?php echo $params['allowOutsideClick']; ?>',
211
+ showLoaderOnConfirm: true,
212
+ }).queue([
213
+ {
214
+ title: '<p class="ig-feedback-title"><?php echo esc_js($params['title']); ?></p>',
215
+ html: '<?php echo $html; ?>',
216
+ customClass: {
217
+ popup: 'animated fadeInUpBig'
218
+ },
219
+ onOpen: () => {
220
+ var clicked = false;
221
+ var selectedReaction = '';
222
+ jQuery('.ig-emoji').hover(function() {
223
+ reaction = jQuery(this).attr('data-reaction');
224
+ jQuery('#emoji-info').text(reaction);
225
+ }, function() {
226
+ if(!clicked) {
227
+ jQuery('#emoji-info').text('');
228
+ } else {
229
+ jQuery('#emoji-info').text(selectedReaction);
230
+ }
231
+ });
232
+
233
+ jQuery('.ig-emoji').on('click', function(){
234
+ clicked = true;
235
+ jQuery('.ig-emoji').removeClass('active');
236
+ jQuery(this).addClass('active');
237
+ selectedReaction = jQuery(this).attr('data-reaction');
238
+ jQuery('#emoji-info').text(reaction);
239
+ });
240
+ },
241
+ preConfirm: () => {
242
+
243
+ var rating = jQuery("input[name='rating']:checked").val();
244
+
245
+ if (rating === undefined) {
246
+ Swal.showValidationMessage('Please give your input');
247
+ return;
248
+ }
249
+
250
+ Swal.insertQueueStep({
251
+ input: 'textarea',
252
+ //html: '<textarea class="swal2-textarea" id="details" placeholder style="display: flex;"></textarea>' +
253
+ // '<p class="info"><input type="checkbox" name="permission" class="anonymous_data_collection" value="1" id="anonymous_data_collection">Help us to improve by opting in to our anonymous plugin data collection.</p>',
254
+ confirmButtonText: 'Send',
255
+ title: '<p class="ig-feedback-title">Anything else you would like to share about your experience</p>',
256
+ showLoaderOnConfirm: true,
257
+
258
+ preConfirm: (details) => {
259
+
260
+ //var enable_system_info = document.getElementById('anonymous_data_collection').checked;
261
+ //var details = document.getElementById('details').value;
262
+
263
+ return doSend(rating, details);
264
+
265
+ }
266
+ });
267
+ }
268
+ },
269
+
270
+ ]).then(response => {
271
+
272
+ if (response.hasOwnProperty('value')) {
273
+
274
+ Swal.fire({
275
+ type: 'success',
276
+ width: <?php echo $params['width']; ?>,
277
+ title: "Thank You!",
278
+ showConfirmButton: false,
279
+ position: '<?php echo $params['position']; ?>',
280
+ timer: 1500,
281
+ animation: false
282
+ });
283
+
284
+ } else if(response.hasOwnProperty('dismiss')) {
285
+ doSend(0, 'dismiss');
286
+ }
287
+ });
288
+ </script>
289
+ <?php
290
+ }
291
+
292
+ /**
293
+ * Render star feedback widget
294
+ *
295
+ * @param array $params
296
+ *
297
+ * @since 1.0.1
298
+ */
299
+ public function render_stars( $params = array() ) {
300
+
301
+ ob_start();
302
+
303
+ ?>
304
+
305
+ <div class="rating">
306
+ <!--elements are in reversed order, to allow "previous sibling selectors" in CSS-->
307
+ <input class="ratings" type="radio" name="rating" value="5" id="5"><label for="5">☆</label>
308
+ <input class="ratings" type="radio" name="rating" value="4" id="4"><label for="4">☆</label>
309
+ <input class="ratings" type="radio" name="rating" value="3" id="3"><label for="3">☆</label>
310
+ <input class="ratings" type="radio" name="rating" value="2" id="2"><label for="2">☆</label>
311
+ <input class="ratings" type="radio" name="rating" value="1" id="1"><label for="1">☆</label>
312
+ </div>
313
+
314
+ <?php
315
+
316
+ $html = str_replace( array( "\r", "\n" ), '', trim( ob_get_clean() ) );
317
+
318
+ $params['html'] = $html;
319
+
320
+ $this->render_widget( $params );
321
+ }
322
+
323
+ /**
324
+ * Render Emoji Widget
325
+ *
326
+ * @param array $params
327
+ *
328
+ * @since 1.0.1
329
+ */
330
+ public function render_emoji( $params = array() ) {
331
+
332
+ ob_start();
333
+
334
+ ?>
335
+
336
+ <div class="emoji">
337
+ <!--elements are in reversed order, to allow "previous sibling selectors" in CSS-->
338
+ <input class="emojis" type="radio" name="rating" value="love" id="5"/><label for="5" class="ig-emoji" data-reaction="Love">😍</label>
339
+ <input class="emojis" type="radio" name="rating" value="smile" id="4"/><label for="4" class="ig-emoji" data-reaction="Smile">😊</label>
340
+ <input class="emojis" type="radio" name="rating" value="neutral" id="3"/><label for="3" class="ig-emoji" data-reaction="Neutral">😐</label>
341
+ <input class="emojis" type="radio" name="rating" value="sad" id="1"/><label for="2" class="ig-emoji" data-reaction="Sad">😠</label>
342
+ <input class="emojis" type="radio" name="rating" value="angry" id="1"/><label for="1" class="ig-emoji" data-reaction="Angry">😡</label>
343
+ </div>
344
+ <div id="emoji-info"></div>
345
+
346
+ <?php
347
+
348
+ $html = str_replace( array( "\r", "\n" ), '', trim( ob_get_clean() ) );
349
+
350
+ $params['html'] = $html;
351
+
352
+ $this->render_widget( $params );
353
+
354
+ }
355
+
356
+ /**
357
+ * Get Feedback API url
358
+ *
359
+ * @param $is_dev_mode
360
+ *
361
+ * @return string
362
+ *
363
+ * @since 1.0.1
364
+ */
365
+ public function get_api_url( $is_dev_mode ) {
366
+
367
+ if ( $is_dev_mode ) {
368
+ $this->api_url = 'http://192.168.0.130:9094/store/feedback/';
369
+ }
370
+
371
+ return $this->api_url;
372
+ }
373
+
374
+ /**
375
+ * Deactivation Survey javascript.
376
+ *
377
+ * @since 1.0.0
378
+ */
379
+ public function js() {
380
+
381
+ if ( ! $this->is_plugin_page() ) {
382
+ return;
383
+ }
384
+
385
+ $title = 'Why are you deactivating Email Subscribers?';
386
+ $slug = sanitize_title( $title );
387
+ $event = $this->event_prefix . 'plugin.deactivation';
388
+
389
+ ?>
390
+ <script type="text/javascript">
391
+ jQuery(function ($) {
392
+ var $deactivateLink = $('#the-list').find('[data-slug="<?php echo $this->plugin; ?>"] span.deactivate a'),
393
+ $overlay = $('#ig-deactivate-survey-<?php echo $this->plugin; ?>'),
394
+ $form = $overlay.find('form'),
395
+ formOpen = false;
396
+ // Plugin listing table deactivate link.
397
+ $deactivateLink.on('click', function (event) {
398
+ event.preventDefault();
399
+ $overlay.css('display', 'table');
400
+ formOpen = true;
401
+ $form.find('.ig-deactivate-survey-option:first-of-type input[type=radio]').focus();
402
+ });
403
+ // Survey radio option selected.
404
+ $form.on('change', 'input[type=radio]', function (event) {
405
+ event.preventDefault();
406
+ $form.find('input[type=text], .error').hide();
407
+ $form.find('.ig-deactivate-survey-option').removeClass('selected');
408
+ $(this).closest('.ig-deactivate-survey-option').addClass('selected').find('input[type=text]').show();
409
+ });
410
+ // Survey Skip & Deactivate.
411
+ $form.on('click', '.ig-deactivate-survey-deactivate', function (event) {
412
+ event.preventDefault();
413
+ location.href = $deactivateLink.attr('href');
414
+ });
415
+ // Survey submit.
416
+ $form.submit(function (event) {
417
+ event.preventDefault();
418
+ if (!$form.find('input[type=radio]:checked').val()) {
419
+ $form.find('.ig-deactivate-survey-footer').prepend('<span class="error"><?php echo esc_js( __( 'Please select an option', 'email-subscribers' ) ); ?></span>');
420
+ return;
421
+ }
422
+
423
+ var data = {
424
+ action: '<?php echo $this->ajax_action; ?>',
425
+ feedback: {
426
+ type: 'radio',
427
+ title: '<?php echo $title; ?>',
428
+ slug: '<?php echo $slug; ?>',
429
+ value: $form.find('.selected input[type=radio]').attr('data-option-slug'),
430
+ details: $form.find('.selected input[type=text]').val()
431
+ },
432
+
433
+ event: '<?php echo $event; ?>',
434
+
435
+ // Add additional information
436
+ misc: {
437
+ plugin: '<?php echo $this->plugin; ?>',
438
+ plugin_abbr: '<?php echo $this->plugin_abbr; ?>',
439
+ is_dev_mode: '<?php echo $this->is_dev_mode; ?>',
440
+ set_cookie: ''
441
+ }
442
+ };
443
+
444
+ var submitSurvey = $.post(ajaxurl, data);
445
+ submitSurvey.always(function () {
446
+ location.href = $deactivateLink.attr('href');
447
+ });
448
+ });
449
+ // Exit key closes survey when open.
450
+ $(document).keyup(function (event) {
451
+ if (27 === event.keyCode && formOpen) {
452
+ $overlay.hide();
453
+ formOpen = false;
454
+ $deactivateLink.focus();
455
+ }
456
+ });
457
+ });
458
+ </script>
459
+ <?php
460
+ }
461
+
462
+ /**
463
+ * Survey CSS.
464
+ *
465
+ * @since 1.0.0
466
+ */
467
+ public function css() {
468
+
469
+ if ( ! $this->is_plugin_page() ) {
470
+ return;
471
+ }
472
+ ?>
473
+ <style type="text/css">
474
+ .ig-deactivate-survey-modal {
475
+ display: none;
476
+ table-layout: fixed;
477
+ position: fixed;
478
+ z-index: 9999;
479
+ width: 100%;
480
+ height: 100%;
481
+ text-align: center;
482
+ font-size: 14px;
483
+ top: 0;
484
+ left: 0;
485
+ background: rgba(0, 0, 0, 0.8);
486
+ }
487
+
488
+ .ig-deactivate-survey-wrap {
489
+ display: table-cell;
490
+ vertical-align: middle;
491
+ }
492
+
493
+ .ig-deactivate-survey {
494
+ background-color: #fff;
495
+ max-width: 550px;
496
+ margin: 0 auto;
497
+ padding: 30px;
498
+ text-align: left;
499
+ }
500
+
501
+ .ig-deactivate-survey .error {
502
+ display: block;
503
+ color: red;
504
+ margin: 0 0 10px 0;
505
+ }
506
+
507
+ .ig-deactivate-survey-title {
508
+ display: block;
509
+ font-size: 18px;
510
+ font-weight: 700;
511
+ text-transform: uppercase;
512
+ border-bottom: 1px solid #ddd;
513
+ padding: 0 0 18px 0;
514
+ margin: 0 0 18px 0;
515
+ }
516
+
517
+ .ig-deactivate-survey-title span {
518
+ color: #999;
519
+ margin-right: 10px;
520
+ }
521
+
522
+ .ig-deactivate-survey-desc {
523
+ display: block;
524
+ font-weight: 600;
525
+ margin: 0 0 18px 0;
526
+ }
527
+
528
+ .ig-deactivate-survey-option {
529
+ margin: 0 0 10px 0;
530
+ }
531
+
532
+ .ig-deactivate-survey-option-input {
533
+ margin-right: 10px !important;
534
+ }
535
+
536
+ .ig-deactivate-survey-option-details {
537
+ display: none;
538
+ width: 90%;
539
+ margin: 10px 0 0 30px;
540
+ }
541
+
542
+ .ig-deactivate-survey-footer {
543
+ margin-top: 18px;
544
+ }
545
+
546
+ .ig-deactivate-survey-deactivate {
547
+ float: right;
548
+ font-size: 13px;
549
+ color: #ccc;
550
+ text-decoration: none;
551
+ padding-top: 7px;
552
+ }
553
+ </style>
554
+ <?php
555
+ }
556
+
557
+ /**
558
+ * Survey modal.
559
+ *
560
+ * @since 1.0.0
561
+ */
562
+ public function modal() {
563
+
564
+ if ( ! $this->is_plugin_page() ) {
565
+ return;
566
+ }
567
+
568
+ $options = array(
569
+ 1 => array(
570
+ 'title' => esc_html__( 'I no longer need the plugin', 'email-subscribers' ),
571
+ 'slug' => 'i-no-longer-need-the-plugin'
572
+ ),
573
+ 2 => array(
574
+ 'title' => esc_html__( 'I\'m switching to a different plugin', 'email-subscribers' ),
575
+ 'slug' => 'i-am-switching-to-a-different-plugin',
576
+ 'details' => esc_html__( 'Please share which plugin', 'email-subscribers' ),
577
+ ),
578
+ 3 => array(
579
+ 'title' => esc_html__( 'I couldn\'t get the plugin to work', 'email-subscribers' ),
580
+ 'slug' => 'i-could-not-get-the-plugin-to-work'
581
+ ),
582
+ 4 => array(
583
+ 'title' => esc_html__( 'It\'s a temporary deactivation', 'email-subscribers' ),
584
+ 'slug' => 'it-is-a-temporary-deactivation'
585
+ ),
586
+ 5 => array(
587
+ 'title' => esc_html__( 'Other', 'email-subscribers' ),
588
+ 'slug' => 'other',
589
+ 'details' => esc_html__( 'Please share the reason', 'email-subscribers' ),
590
+ ),
591
+ );
592
+ ?>
593
+ <div class="ig-deactivate-survey-modal" id="ig-deactivate-survey-<?php echo $this->plugin; ?>">
594
+ <div class="ig-deactivate-survey-wrap">
595
+ <form class="ig-deactivate-survey" method="post">
596
+ <span class="ig-deactivate-survey-title"><span class="dashicons dashicons-testimonial"></span><?php echo ' ' . esc_html__( 'Quick Feedback', 'email-subscribers' ); ?></span>
597
+ <span class="ig-deactivate-survey-desc"><?php echo sprintf( esc_html__( 'If you have a moment, please share why you are deactivating %s:', 'email-subscribers' ), $this->name ); ?></span>
598
+ <div class="ig-deactivate-survey-options">
599
+ <?php foreach ( $options as $id => $option ) : ?>
600
+ <div class="ig-deactivate-survey-option">
601
+ <label for="ig-deactivate-survey-option-<?php echo $this->plugin; ?>-<?php echo $id; ?>" class="ig-deactivate-survey-option-label">
602
+ <input id="ig-deactivate-survey-option-<?php echo $this->plugin; ?>-<?php echo $id; ?>" class="ig-deactivate-survey-option-input" type="radio" name="code" value="<?php echo $id; ?>" data-option-slug="<?php echo $option['slug']; ?>"/>
603
+ <span class="ig-deactivate-survey-option-reason"><?php echo $option['title']; ?></span>
604
+ </label>
605
+ <?php if ( ! empty( $option['details'] ) ) : ?>
606
+ <input class="ig-deactivate-survey-option-details" type="text" placeholder="<?php echo $option['details']; ?>"/>
607
+ <?php endif; ?>
608
+ </div>
609
+ <?php endforeach; ?>
610
+ </div>
611
+ <div class="ig-deactivate-survey-footer">
612
+ <button type="submit" class="ig-deactivate-survey-submit button button-primary button-large"><?php echo sprintf( esc_html__( 'Submit %s Deactivate', 'email-subscribers' ), '&amp;' ); ?></button>
613
+ <a href="#" class="ig-deactivate-survey-deactivate"><?php echo sprintf( esc_html__( 'Skip %s Deactivate', 'email-subscribers' ), '&amp;' ); ?></a>
614
+ </div>
615
+ </form>
616
+ </div>
617
+ </div>
618
+ <?php
619
+ }
620
+
621
+ /**
622
+ * Can we show feedback widget in this environment
623
+ *
624
+ * @return bool
625
+ */
626
+ public function can_show_feedback_widget() {
627
+
628
+ // Is development mode? Enable it.
629
+ if ( $this->is_dev_mode ) {
630
+ return true;
631
+ }
632
+
633
+ // Don't show on dev setup if dev mode is off.
634
+ if ( $this->is_dev_url() ) {
635
+ return false;
636
+ }
637
+
638
+ return true;
639
+ }
640
+
641
+ /**
642
+ * Checks if current admin screen is the plugins page.
643
+ *
644
+ * @return bool
645
+ * @since 1.0.0
646
+ */
647
+ public function is_plugin_page() {
648
+
649
+ $screen = function_exists( 'get_current_screen' ) ? get_current_screen() : false;
650
+ if ( empty( $screen ) ) {
651
+ return false;
652
+ }
653
+
654
+ return ( ! empty( $screen->id ) && in_array( $screen->id, array( 'plugins', 'plugins-network' ), true ) );
655
+ }
656
+
657
+
658
+ /**
659
+ * Checks if current site is a development one.
660
+ *
661
+ * @return bool
662
+ *
663
+ * @since 1.0.0
664
+ */
665
+ public function is_dev_url() {
666
+
667
+ $url = network_site_url( '/' );
668
+ $is_local_url = false;
669
+
670
+ // Trim it up
671
+ $url = strtolower( trim( $url ) );
672
+
673
+ // Need to get the host...so let's add the scheme so we can use parse_url
674
+ if ( false === strpos( $url, 'http://' ) && false === strpos( $url, 'https://' ) ) {
675
+ $url = 'http://' . $url;
676
+ }
677
+ $url_parts = parse_url( $url );
678
+ $host = ! empty( $url_parts['host'] ) ? $url_parts['host'] : false;
679
+ if ( ! empty( $url ) && ! empty( $host ) ) {
680
+ if ( false !== ip2long( $host ) ) {
681
+ if ( ! filter_var( $host, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) ) {
682
+ $is_local_url = true;
683
+ }
684
+ } elseif ( 'localhost' === $host ) {
685
+ $is_local_url = true;
686
+ }
687
+
688
+ $tlds_to_check = array( '.dev', '.local', ':8888' );
689
+ foreach ( $tlds_to_check as $tld ) {
690
+ if ( false !== strpos( $host, $tld ) ) {
691
+ $is_local_url = true;
692
+ continue;
693
+ }
694
+
695
+ }
696
+ if ( substr_count( $host, '.' ) > 1 ) {
697
+ $subdomains_to_check = array( 'dev.', '*.staging.', 'beta.', 'test.' );
698
+ foreach ( $subdomains_to_check as $subdomain ) {
699
+ $subdomain = str_replace( '.', '(.)', $subdomain );
700
+ $subdomain = str_replace( array( '*', '(.)' ), '(.*)', $subdomain );
701
+ if ( preg_match( '/^(' . $subdomain . ')/', $host ) ) {
702
+ $is_local_url = true;
703
+ continue;
704
+ }
705
+ }
706
+ }
707
+ }
708
+
709
+ return $is_local_url;
710
+ }
711
+
712
+ /**
713
+ * Store plugin feedback data into option
714
+ *
715
+ * @param $plugin_abbr
716
+ * @param $event
717
+ * @param $data
718
+ *
719
+ * @since 1.0.1
720
+ */
721
+ public function set_feedback_data( $plugin_abbr, $event, $data ) {
722
+
723
+ $feedback_option = $plugin_abbr . '_feedback_data';
724
+
725
+ $feedback_data = maybe_unserialize( get_option( $feedback_option, array() ) );
726
+
727
+ $data['created_on'] = gmdate( 'Y-m-d H:i:s' );
728
+
729
+ $feedback_data[ $event ][] = $data;
730
+
731
+ update_option( $feedback_option, $feedback_data );
732
+
733
+ }
734
+
735
+ /**
736
+ * Get plugin feedback data
737
+ *
738
+ * @param $plugin_abbr
739
+ *
740
+ * @return mixed|void
741
+ *
742
+ * @since 1.0.1
743
+ */
744
+ public function get_feedback_data( $plugin_abbr ) {
745
+
746
+ $feedback_option = $plugin_abbr . '_feedback_data';
747
+
748
+ return get_option( $feedback_option, array() );
749
+ }
750
+
751
+ /**
752
+ * Get event specific feedback data
753
+ *
754
+ * @param $plugin_abbr
755
+ * @param $event
756
+ *
757
+ * @return array|mixed
758
+ */
759
+ public function get_event_feedback_data( $plugin_abbr, $event ) {
760
+
761
+ $feedback_data = $this->get_feedback_data( $plugin_abbr );
762
+
763
+ $event_feedback_data = ! empty( $feedback_data[ $event ] ) ? $feedback_data[ $event ] : array();
764
+
765
+ return $event_feedback_data;
766
+ }
767
+
768
+ /**
769
+ * Set event into transient
770
+ *
771
+ * @param $event
772
+ * @param int $expiry in days
773
+ */
774
+ public function set_event_transient( $event, $expiry = 45 ) {
775
+ set_transient( $event, 1, time() + ( 86400 * $expiry ) );
776
+ }
777
+
778
+ /**
779
+ * Check whether event transient is set or not.
780
+ *
781
+ * @param $event
782
+ *
783
+ * @return bool
784
+ *
785
+ * @since 1.0.1
786
+ */
787
+ public function is_event_transient_set( $event ) {
788
+ return get_transient( $event );
789
+ }
790
+
791
+ /**
792
+ * Hook to ajax_action
793
+ *
794
+ * Send feedback to server
795
+ */
796
+ function submit_feedback() {
797
+
798
+ $data = ! empty( $_POST ) ? $_POST : array();
799
+
800
+ $data['site'] = esc_url( home_url() );
801
+
802
+ $plugin = ! empty( $data['misc']['plugin'] ) ? $data['misc']['plugin'] : 'ig_feedback';
803
+ $plugin_abbr = ! empty( $data['misc']['plugin_abbr'] ) ? $data['misc']['plugin_abbr'] : 'ig_feedback';
804
+ $is_dev_mode = ! empty( $data['misc']['is_dev_mode'] ) ? $data['misc']['is_dev_mode'] : false;
805
+ $set_transient = ! empty( $data['misc']['set_transient'] ) ? $data['misc']['set_transient'] : false;
806
+ $system_info = ! empty( $data['misc']['system_info'] ) ? $data['misc']['system_info'] : false;
807
+
808
+ $logger = get_ig_logger();
809
+ $logger->info('DAta' . print_r($data, true));
810
+
811
+ unset( $data['misc'] );
812
+
813
+ $meta_info = array(
814
+ 'plugin' => sanitize_key( $plugin ),
815
+ 'locale' => get_locale(),
816
+ 'wp_version' => get_bloginfo( 'version' )
817
+ );
818
+
819
+ $additional_info = array();
820
+ $additional_info = apply_filters( $plugin_abbr . '_additional_feedback_meta_info', $additional_info, $system_info ); // Get Additional meta information
821
+
822
+ if ( is_array( $additional_info ) && count( $additional_info ) > 0 ) {
823
+ $meta_info = $meta_info + $additional_info;
824
+ }
825
+
826
+ $data['meta'] = $meta_info;
827
+
828
+ $data = wp_unslash($data);
829
+
830
+ $args = array(
831
+ 'timeout' => 15,
832
+ 'sslverify' => false,
833
+ 'body' => $data,
834
+ 'blocking' => false
835
+ );
836
+
837
+ $this->set_feedback_data( $plugin_abbr, $data['event'], $data['feedback'] );
838
+
839
+ // Set Cookie
840
+ if ( $set_transient ) {
841
+ $this->set_event_transient( $data['event'] );
842
+ }
843
+
844
+ $logger->info('DAta' . print_r($data, true));
845
+
846
+ $response = wp_remote_post( $this->get_api_url( $is_dev_mode ), $args );
847
+
848
+ $result['status'] = 'success';
849
+ if ( $response instanceof WP_Error ) {
850
+ $error_message = $response->get_error_message();
851
+ $result['status'] = 'error';
852
+ $result['message'] = $error_message;
853
+ }
854
+
855
+ die( json_encode( $result ) );
856
+ }
857
+ }
858
+ } // End if().
includes/feedback/{class-ig-tracker.php → class-ig-tracker-v-1-0-1.php} RENAMED
@@ -4,7 +4,7 @@ if ( ! defined( 'ABSPATH' ) ) {
4
  exit; // Exit if accessed directly.
5
  }
6
 
7
- if ( ! class_exists( 'IG_Tracker' ) ) {
8
 
9
  /**
10
  * Icegram tracker.
@@ -14,10 +14,10 @@ if ( ! class_exists( 'IG_Tracker' ) ) {
14
  *
15
  * @since 1.0.0
16
  */
17
- class IG_Tracker {
18
 
19
  /**
20
- * Get Active & Inactive plugins info
21
  *
22
  * @return array
23
  *
@@ -65,10 +65,10 @@ if ( ! class_exists( 'IG_Tracker' ) ) {
65
 
66
  if ( 'active' === $status ) {
67
  return $plugins['active_plugins'];
68
- } elseif ( 'in_active' === $status ) {
69
  return $plugins['inactive_plugins'];
70
- } else {
71
- return $plugins;
72
  }
73
  }
74
 
@@ -94,8 +94,8 @@ if ( ! class_exists( 'IG_Tracker' ) ) {
94
  *
95
  * @since 1.0.0
96
  */
97
- public static function get_in_active_plugins( $details = false ) {
98
- return self::get_plugins( 'in_active', $details );
99
  }
100
 
101
  /**
4
  exit; // Exit if accessed directly.
5
  }
6
 
7
+ if ( ! class_exists( 'IG_Tracker_V_1_0_1' ) ) {
8
 
9
  /**
10
  * Icegram tracker.
14
  *
15
  * @since 1.0.0
16
  */
17
+ class IG_Tracker_V_1_0_1 {
18
 
19
  /**
20
+ * Get Active, Inactive or all plugins info
21
  *
22
  * @return array
23
  *
65
 
66
  if ( 'active' === $status ) {
67
  return $plugins['active_plugins'];
68
+ } elseif ( 'inactive' === $status ) {
69
  return $plugins['inactive_plugins'];
70
+ } elseif('all' === $status) {
71
+ return array_merge($plugins['active_plugins'], $plugins['inactive_plugins']);
72
  }
73
  }
74
 
94
  *
95
  * @since 1.0.0
96
  */
97
+ public static function get_inactive_plugins( $details = false ) {
98
+ return self::get_plugins( 'inactive', $details );
99
  }
100
 
101
  /**
includes/pro-features.php CHANGED
@@ -23,7 +23,7 @@ function ig_es_add_upsale( $fields ) {
23
  'id' => 'ig_es_blocked_domains',
24
  'type' => 'html',
25
  'name' => '',
26
- 'html' => '<div class="es-upsale-image" style=""><a target="_blank" href="https://www.icegram.com/email-subscribers-starter/?utm_source=in_app&utm_medium=es_security_settings&utm_campaign=es_upsale"><img src="' . EMAIL_SUBSCRIBERS_URL . '/admin/images/es-captcha-2.png' . '"/></a></div>'
27
  );
28
  $fields['security_settings'] = array_merge( $fields['security_settings'], $field_security );
29
 
@@ -31,7 +31,7 @@ function ig_es_add_upsale( $fields ) {
31
  $field_smtp['es_upsale_smtp'] = array(
32
  'id' => 'ig_es_blocked_domains',
33
  'type' => 'html',
34
- 'name' => '<div class="es-smtp-label" style=""><a target="_blank" href="https://www.icegram.com/email-subscribers-starter/?utm_source=in_app&utm_medium=es_smtp&utm_campaign=es_upsale"><img src="' . EMAIL_SUBSCRIBERS_URL . '/admin/images/es-smtp-label.png' . '"/></a></div>',
35
  'html' => '<div class="es-upsale-image es-smtp-image" style=""><a target="_blank" href="https://www.icegram.com/email-subscribers-starter/?utm_source=in_app&utm_medium=es_smtp&utm_campaign=es_upsale"><img src="' . EMAIL_SUBSCRIBERS_URL . '/admin/images/es-smtp.png' . '"/></a></div>'
36
  );
37
  $fields['email_sending'] = array_merge( $fields['email_sending'], $field_smtp );
@@ -83,16 +83,16 @@ function ig_es_add_comments_tab_settings( $tab_options ) {
83
  <h2>Sync Comment Users</h2>
84
  <p>Quickly add to your mailing list when someone post a comment on your website.</p>
85
  <h2>How to setup?</h2>
86
- <p>Once you upgrade to <a href="https://www.icegram.com/email-subscribers-starter/?utm_source=in_app&utm_medium=woocommerce_sync&utm_campaign=es_upsale">Email Subscribers Starter</a>, you will have settings panel where you need to enable Comment user sync and select the list in which you want to add people whenever someone post a comment.</p>
87
  <hr>
88
- <p class="help">Checkout <a href="https://www.icegram.com/email-subscribers-starter/?utm_source=in_app&utm_medium=woocommerce_sync&utm_campaign=es_upsale">Email Subscribers Starter</a> Plan Now</p>
89
  </div>
90
  <?php
91
 
92
  $content = ob_get_clean();
93
 
94
  ?>
95
- <a target="_blank" href="https://www.icegram.com/email-subscribers-starter/?utm_source=in_app&utm_medium=es_comment_upsale&utm_campaign=es_upsale">
96
  <img src=" <?php echo EMAIL_SUBSCRIBERS_URL . '/admin/images/es-comments.png' ?> "/>
97
  </a>
98
  <?php
@@ -111,14 +111,14 @@ function ig_es_add_woocommerce_tab_settings( $tab_options ) {
111
  <h2>Sync WooCommerce Customers</h2>
112
  <p>Are you using WooCommerce for your online business? You can use this integration to add to a specific list whenever someone purchase something from you</p>
113
  <h2>How to setup?</h2>
114
- <p>Once you upgrade to <a href="https://www.icegram.com/email-subscribers-starter/?utm_source=in_app&utm_medium=woocommerce_sync&utm_campaign=es_upsale">Email Subscribers Starter</a>, you will have following settings panel where you need to enable WooCommerce sync and select the list in which you want to add people whenever they purchase something
115
  from you.</p>
116
  <hr>
117
- <p class="help">Checkout <a href="https://www.icegram.com/email-subscribers-starter/?utm_source=in_app&utm_medium=woocommerce_sync&utm_campaign=es_upsale">Email Subscribers Starter</a> Now</p>
118
  </div>
119
  <?php $content = ob_get_clean(); ?>
120
 
121
- <a target="_blank" href="https://www.icegram.com/email-subscribers-starter/?utm_source=in_app&utm_medium=es_comment_upsale&utm_campaign=es_upsale">
122
  <img src=" <?php echo EMAIL_SUBSCRIBERS_URL . '/admin/images/woocommerce-sync.png' ?> "/>
123
  </a>
124
 
23
  'id' => 'ig_es_blocked_domains',
24
  'type' => 'html',
25
  'name' => '',
26
+ 'html' => '<div class="es-upsale-image" style=""><a target="_blank" href="https://www.icegram.com/email-subscribers-starter/?utm_source=in_app&utm_medium=es_security_settings&utm_campaign=es_upsale#blockspam"><img src="' . EMAIL_SUBSCRIBERS_URL . '/admin/images/es-captcha-2.png' . '"/></a></div>'
27
  );
28
  $fields['security_settings'] = array_merge( $fields['security_settings'], $field_security );
29
 
31
  $field_smtp['es_upsale_smtp'] = array(
32
  'id' => 'ig_es_blocked_domains',
33
  'type' => 'html',
34
+ 'name' => '<div class="es-smtp-label" style=""><a target="_blank" href="https://www.icegram.com/email-subscribers-starter/?utm_source=in_app&utm_medium=es_smtp&utm_campaign=es_upsale#delivery"><img src="' . EMAIL_SUBSCRIBERS_URL . '/admin/images/es-smtp-label.png' . '"/></a></div>',
35
  'html' => '<div class="es-upsale-image es-smtp-image" style=""><a target="_blank" href="https://www.icegram.com/email-subscribers-starter/?utm_source=in_app&utm_medium=es_smtp&utm_campaign=es_upsale"><img src="' . EMAIL_SUBSCRIBERS_URL . '/admin/images/es-smtp.png' . '"/></a></div>'
36
  );
37
  $fields['email_sending'] = array_merge( $fields['email_sending'], $field_smtp );
83
  <h2>Sync Comment Users</h2>
84
  <p>Quickly add to your mailing list when someone post a comment on your website.</p>
85
  <h2>How to setup?</h2>
86
+ <p>Once you upgrade to <a href="https://www.icegram.com/email-subscribers-starter/?utm_source=in_app&utm_medium=comment_sync&utm_campaign=es_upsale#sync_comment_users">Email Subscribers Starter</a>, you will have settings panel where you need to enable Comment user sync and select the list in which you want to add people whenever someone post a comment.</p>
87
  <hr>
88
+ <p class="help">Checkout <a href="https://www.icegram.com/email-subscribers-starter/?utm_source=in_app&utm_medium=comment_sync&utm_campaign=es_upsale#sync_comment_users">Email Subscribers Starter</a> Plan Now</p>
89
  </div>
90
  <?php
91
 
92
  $content = ob_get_clean();
93
 
94
  ?>
95
+ <a target="_blank" href="https://www.icegram.com/email-subscribers-starter/?utm_source=in_app&utm_medium=es_comment_upsale&utm_campaign=es_upsale#sync_comment_users">
96
  <img src=" <?php echo EMAIL_SUBSCRIBERS_URL . '/admin/images/es-comments.png' ?> "/>
97
  </a>
98
  <?php
111
  <h2>Sync WooCommerce Customers</h2>
112
  <p>Are you using WooCommerce for your online business? You can use this integration to add to a specific list whenever someone purchase something from you</p>
113
  <h2>How to setup?</h2>
114
+ <p>Once you upgrade to <a href="https://www.icegram.com/email-subscribers-starter/?utm_source=in_app&utm_medium=woocommerce_sync&utm_campaign=es_upsale#sync_woocommerce_customers">Email Subscribers Starter</a>, you will have following settings panel where you need to enable WooCommerce sync and select the list in which you want to add people whenever they purchase something
115
  from you.</p>
116
  <hr>
117
+ <p class="help">Checkout <a href="https://www.icegram.com/email-subscribers-starter/?utm_source=in_app&utm_medium=woocommerce_sync&utm_campaign=es_upsale#sync_woocommerce_customers">Email Subscribers Starter</a> Now</p>
118
  </div>
119
  <?php $content = ob_get_clean(); ?>
120
 
121
+ <a target="_blank" href="https://www.icegram.com/email-subscribers-starter/?utm_source=in_app&utm_medium=woocommerce_sync&utm_campaign=es_upsale#sync_woocommerce_customers">
122
  <img src=" <?php echo EMAIL_SUBSCRIBERS_URL . '/admin/images/woocommerce-sync.png' ?> "/>
123
  </a>
124
 
includes/upgrade/es-update-functions.php CHANGED
@@ -462,8 +462,6 @@ function ig_es_update_400_import_options() {
462
  update_option( $option, $value );
463
  }
464
  }
465
-
466
-
467
  }
468
 
469
  function ig_es_update_400_migrate_lists() {
462
  update_option( $option, $value );
463
  }
464
  }
 
 
465
  }
466
 
467
  function ig_es_update_400_migrate_lists() {
public/class-email-subscribers-public.php CHANGED
@@ -204,6 +204,15 @@ class Email_Subscribers_Public {
204
 
205
  $email = $contact_data['email'];
206
 
 
 
 
 
 
 
 
 
 
207
  $contact = ES_DB_Contacts::is_subscriber_exist_in_list( $email, $list_id );
208
  if ( empty( $contact['contact_id'] ) ) {
209
  $contact_id = ES_DB_Contacts::add_subscriber( $contact_data );
@@ -226,6 +235,7 @@ class Email_Subscribers_Public {
226
  );
227
 
228
  ES_DB_Lists_Contacts::delete_list_contacts( $contact_id, array($list_id) );
 
229
  $result = ES_DB_Lists_Contacts::add_lists_contacts( $list_contact_data );
230
  }
231
 
204
 
205
  $email = $contact_data['email'];
206
 
207
+ $default_data = array(
208
+ 'status' => 'verified',
209
+ 'hash' => ES_Common::generate_guid(),
210
+ 'created_at' => ig_get_current_date_time(),
211
+ 'wp_user_id' => 0
212
+ );
213
+
214
+ $contact_data = wp_parse_args($contact_data, $default_data);
215
+
216
  $contact = ES_DB_Contacts::is_subscriber_exist_in_list( $email, $list_id );
217
  if ( empty( $contact['contact_id'] ) ) {
218
  $contact_id = ES_DB_Contacts::add_subscriber( $contact_data );
235
  );
236
 
237
  ES_DB_Lists_Contacts::delete_list_contacts( $contact_id, array($list_id) );
238
+
239
  $result = ES_DB_Lists_Contacts::add_lists_contacts( $list_contact_data );
240
  }
241
 
readme.txt CHANGED
@@ -5,7 +5,7 @@ Author URI: https://www.icegram.com/
5
  Tags: subscription, newsletter, email marketing, post notification, email newsletter form, email signup, email widget, newsletter signup, subscribe, subscription form, bulk emails, signup form, list builder, lead generation, welcome email, contacts
6
  Requires at least: 3.9
7
  Tested up to: 5.2
8
- Stable tag: 4.1.1
9
  License: GPLv3
10
  License URI: http://www.gnu.org/licenses
11
 
@@ -301,6 +301,9 @@ Use our free plugin [Email Subscribers - Group Selector](https://wordpress.org/p
301
 
302
  == Changelog ==
303
 
 
 
 
304
  = 4.1.1 (21.05.2019) =
305
  * Fix: "Oops.. Unexpected error occurred" while subscribing
306
  * Fix: Typo in "Campaigns > Edit Post Notification" title
5
  Tags: subscription, newsletter, email marketing, post notification, email newsletter form, email signup, email widget, newsletter signup, subscribe, subscription form, bulk emails, signup form, list builder, lead generation, welcome email, contacts
6
  Requires at least: 3.9
7
  Tested up to: 5.2
8
+ Stable tag: 4.1.2
9
  License: GPLv3
10
  License URI: http://www.gnu.org/licenses
11
 
301
 
302
  == Changelog ==
303
 
304
+ = 4.1.2 (29.05.2019) =
305
+ * New: Added support to export "Unconfirmed" contacts.
306
+
307
  = 4.1.1 (21.05.2019) =
308
  * Fix: "Oops.. Unexpected error occurred" while subscribing
309
  * Fix: Typo in "Campaigns > Edit Post Notification" title