diff --git a/wp-content/plugins/akismet/akismet.php b/wp-content/plugins/akismet/akismet.php
index d4f21350b3719890e97fcb8ad2a2d06706a30ca1..800dd724532ce26bc534b50d87bdd17de137c8fd 100644
--- a/wp-content/plugins/akismet/akismet.php
+++ b/wp-content/plugins/akismet/akismet.php
@@ -6,7 +6,7 @@
 Plugin Name: Akismet Anti-Spam
 Plugin URI: https://akismet.com/
 Description: Used by millions, Akismet is quite possibly the best way in the world to <strong>protect your blog from spam</strong>. It keeps your site protected even while you sleep. To get started: activate the Akismet plugin and then go to your Akismet Settings page to set up your API key.
-Version: 4.0.8
+Version: 4.1
 Author: Automattic
 Author URI: https://automattic.com/wordpress-plugins/
 License: GPLv2 or later
@@ -37,7 +37,7 @@ if ( !function_exists( 'add_action' ) ) {
 	exit;
 }
 
-define( 'AKISMET_VERSION', '4.0.8' );
+define( 'AKISMET_VERSION', '4.1' );
 define( 'AKISMET__MINIMUM_WP_VERSION', '4.0' );
 define( 'AKISMET__PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
 define( 'AKISMET_DELETE_LIMIT', 100000 );
diff --git a/wp-content/plugins/akismet/class.akismet-admin.php b/wp-content/plugins/akismet/class.akismet-admin.php
index 1e80617355054cee1563882016c474223afe4ff0..07a4d19352410776ce5f1e41a9ed5ff3b3c0eefb 100644
--- a/wp-content/plugins/akismet/class.akismet-admin.php
+++ b/wp-content/plugins/akismet/class.akismet-admin.php
@@ -74,6 +74,9 @@ class Akismet_Admin {
 			add_filter( 'akismet_comment_form_privacy_notice_url_display',  array( 'Akismet_Admin', 'jetpack_comment_form_privacy_notice_url' ) );
 			add_filter( 'akismet_comment_form_privacy_notice_url_hide',     array( 'Akismet_Admin', 'jetpack_comment_form_privacy_notice_url' ) );
 		}
+
+		// priority=1 because we need ours to run before core's comment anonymizer runs, and that's registered at priority=10
+		add_filter( 'wp_privacy_personal_data_erasers', array( 'Akismet_Admin', 'register_personal_data_eraser' ), 1 );
 	}
 
 	public static function admin_init() {
@@ -1049,7 +1052,7 @@ class Akismet_Admin {
 				$message .= ' ';
 			
 				if ( $spam_count === 0 ) {
-					$message .= __( 'No comments were caught as spam.' );
+					$message .= __( 'No comments were caught as spam.', 'akismet' );
 				}
 				else {
 					$message .= sprintf( _n( '%s comment was caught as spam.', '%s comments were caught as spam.', $spam_count, 'akismet' ), number_format( $spam_count ) );
@@ -1180,4 +1183,62 @@ class Akismet_Admin {
 	public static function jetpack_comment_form_privacy_notice_url( $url ) {
 		return str_replace( 'options-general.php', 'admin.php', $url );
 	}
+	
+	public static function register_personal_data_eraser( $erasers ) {
+		$erasers['akismet'] = array(
+			'eraser_friendly_name' => __( 'Akismet', 'akismet' ),
+			'callback' => array( 'Akismet_Admin', 'erase_personal_data' ),
+		);
+
+		return $erasers;
+	}
+	
+	/**
+	 * When a user requests that their personal data be removed, Akismet has a duty to discard
+	 * any personal data we store outside of the comment itself. Right now, that is limited
+	 * to the copy of the comment we store in the akismet_as_submitted commentmeta.
+	 *
+	 * FWIW, this information would be automatically deleted after 15 days.
+	 * 
+	 * @param $email_address string The email address of the user who has requested erasure.
+	 * @param $page int This function can (and will) be called multiple times to prevent timeouts,
+	 *                  so this argument is used for pagination.
+	 * @return array
+	 * @see https://developer.wordpress.org/plugins/privacy/adding-the-personal-data-eraser-to-your-plugin/
+	 */
+	public static function erase_personal_data( $email_address, $page = 1 ) {
+		$items_removed = false;
+		
+		$number = 50;
+		$page = (int) $page;
+
+		$comments = get_comments(
+			array(
+				'author_email' => $email_address,
+				'number'       => $number,
+				'paged'        => $page,
+				'order_by'     => 'comment_ID',
+				'order'        => 'ASC',
+			)
+		);
+
+		foreach ( (array) $comments as $comment ) {
+			$comment_as_submitted = get_comment_meta( $comment->comment_ID, 'akismet_as_submitted', true );
+			
+			if ( $comment_as_submitted ) {
+				delete_comment_meta( $comment->comment_ID, 'akismet_as_submitted' );
+				$items_removed = true;
+			}
+		}
+
+		// Tell core if we have more comments to work on still
+		$done = count( $comments ) < $number;
+		
+		return array(
+			'items_removed' => $items_removed,
+			'items_retained' => false, // always false in this example
+			'messages' => array(), // no messages in this example
+			'done' => $done,
+		);
+	}
 }
diff --git a/wp-content/plugins/akismet/class.akismet-cli.php b/wp-content/plugins/akismet/class.akismet-cli.php
index b0b483670acd3bd2a9999b5e949c88d4d85cbf97..9cbe7a92468e7c8992d79cfee5dc7b8ea338e5ea 100644
--- a/wp-content/plugins/akismet/class.akismet-cli.php
+++ b/wp-content/plugins/akismet/class.akismet-cli.php
@@ -88,4 +88,98 @@ class Akismet_CLI extends WP_CLI_Command {
 			WP_CLI::line( sprintf( _n( "%d comment could not be checked.", "%d comments could not be checked.", $total_counts['error'], 'akismet' ), number_format( $total_counts['error'] ) ) );
 		}
 	}
+	
+	/**
+	 * Fetches stats from the Akismet API.
+	 *
+	 * ## OPTIONS
+	 *
+	 * [<interval>]
+	 * : The time period for which to retrieve stats.
+	 * ---
+	 * default: all
+	 * options:
+	 *  - days
+	 *  - months
+	 *  - all
+	 * ---
+	 *
+	 * [--format=<format>]
+	 * : Allows overriding the output of the command when listing connections.
+	 * ---
+	 * default: table
+	 * options:
+	 *  - table
+	 *  - json
+	 *  - csv
+	 *  - yaml
+	 *  - count
+	 * ---
+	 *
+	 * [--summary]
+	 * : When set, will display a summary of the stats.
+	 *
+	 * ## EXAMPLES
+	 *
+	 * wp akismet stats
+	 * wp akismet stats all
+	 * wp akismet stats days
+	 * wp akismet stats months
+	 * wp akismet stats all --summary
+	 */
+	public function stats( $args, $assoc_args ) {
+		$api_key = Akismet::get_api_key();
+ 
+		if ( empty( $api_key ) ) {
+			WP_CLI::error( __( 'API key must be set to fetch stats.', 'akismet' ) );
+		}
+ 
+		switch ( $args[0] ) {
+			case 'days':
+				$interval = '60-days';
+				break;
+			case 'months':
+				$interval = '6-months';
+				break;
+			default:
+				$interval = 'all';
+				break;
+		}
+ 
+		$response = Akismet::http_post(
+			Akismet::build_query( array(
+				'blog' => get_option( 'home' ),
+				'key'  => $api_key,
+				'from' => $interval,
+			) ),
+			'get-stats'
+		);
+ 
+		if ( empty( $response[1] ) ) {
+			WP_CLI::error( __( 'Currently unable to fetch stats. Please try again.', 'akismet' ) );
+		}
+ 
+		$response_body = json_decode( $response[1], true );
+		
+		if ( is_null( $response_body ) ) {
+			WP_CLI::error( __( 'Stats response could not be decoded.', 'akismet' ) );
+		}
+ 
+		if ( isset( $assoc_args['summary'] ) ) {
+			$keys = array(
+				'spam',
+				'ham',
+				'missed_spam',
+				'false_positives',
+				'accuracy',
+				'time_saved',
+			);
+ 
+			WP_CLI\Utils\format_items( $assoc_args['format'], array( $response_body ), $keys );
+		}
+		else {
+			$stats = $response_body['breakdown'];
+			WP_CLI\Utils\format_items( $assoc_args['format'], $stats, array_keys( end( $stats ) ) );
+		}
+	}
 }
\ No newline at end of file
diff --git a/wp-content/plugins/akismet/class.akismet-rest-api.php b/wp-content/plugins/akismet/class.akismet-rest-api.php
index f97b710d3a9ee369bfb5a0e79251c61274ad43a8..bf71998bd6ba4e3ecc663634a5ae8e7ee173842f 100644
--- a/wp-content/plugins/akismet/class.akismet-rest-api.php
+++ b/wp-content/plugins/akismet/class.akismet-rest-api.php
@@ -87,6 +87,48 @@ class Akismet_REST_API {
 				'callback' => array( 'Akismet_REST_API', 'get_stats' ),
 			)
 		) );
+
+		register_rest_route( 'akismet/v1', '/alert', array(
+			array(
+				'methods' => WP_REST_Server::READABLE,
+				'permission_callback' => array( 'Akismet_REST_API', 'remote_call_permission_callback' ),
+				'callback' => array( 'Akismet_REST_API', 'get_alert' ),
+				'args' => array(
+					'key' => array(
+						'required' => false,
+						'type' => 'string',
+						'sanitize_callback' => array( 'Akismet_REST_API', 'sanitize_key' ),
+						'description' => __( 'A 12-character Akismet API key. Available at akismet.com/get/', 'akismet' ),
+					),
+				),
+			),
+			array(
+				'methods' => WP_REST_Server::EDITABLE,
+				'permission_callback' => array( 'Akismet_REST_API', 'remote_call_permission_callback' ),
+				'callback' => array( 'Akismet_REST_API', 'set_alert' ),
+				'args' => array(
+					'key' => array(
+						'required' => false,
+						'type' => 'string',
+						'sanitize_callback' => array( 'Akismet_REST_API', 'sanitize_key' ),
+						'description' => __( 'A 12-character Akismet API key. Available at akismet.com/get/', 'akismet' ),
+					),
+				),
+			),
+			array(
+				'methods' => WP_REST_Server::DELETABLE,
+				'permission_callback' => array( 'Akismet_REST_API', 'remote_call_permission_callback' ),
+				'callback' => array( 'Akismet_REST_API', 'delete_alert' ),
+				'args' => array(
+					'key' => array(
+						'required' => false,
+						'type' => 'string',
+						'sanitize_callback' => array( 'Akismet_REST_API', 'sanitize_key' ),
+						'description' => __( 'A 12-character Akismet API key. Available at akismet.com/get/', 'akismet' ),
+					),
+				),
+			)
+		) );
 	}
 
 	/**
@@ -231,6 +273,50 @@ class Akismet_REST_API {
 		return rest_ensure_response( $stat_totals );
 	}
 
+	/**
+	 * Get the current alert code and message. Alert codes are used to notify the site owner
+	 * if there's a problem, like a connection issue between their site and the Akismet API,
+	 * invalid requests being sent, etc.
+	 *
+	 * @param WP_REST_Request $request
+	 * @return WP_Error|WP_REST_Response
+	 */
+	public static function get_alert( $request ) {
+		return rest_ensure_response( array(
+			'code' => get_option( 'akismet_alert_code' ),
+			'message' => get_option( 'akismet_alert_msg' ),
+		) );
+	}
+
+	/**
+	 * Update the current alert code and message by triggering a call to the Akismet server.
+	 *
+	 * @param WP_REST_Request $request
+	 * @return WP_Error|WP_REST_Response
+	 */
+	public static function set_alert( $request ) {
+		delete_option( 'akismet_alert_code' );
+		delete_option( 'akismet_alert_msg' );
+
+		// Make a request so the most recent alert code and message are retrieved.
+		Akismet::verify_key( Akismet::get_api_key() );
+
+		return self::get_alert( $request );
+	}
+
+	/**
+	 * Clear the current alert code and message.
+	 *
+	 * @param WP_REST_Request $request
+	 * @return WP_Error|WP_REST_Response
+	 */
+	public static function delete_alert( $request ) {
+		delete_option( 'akismet_alert_code' );
+		delete_option( 'akismet_alert_msg' );
+
+		return self::get_alert( $request );
+	}
+
 	private static function key_is_valid( $key ) {
 		$response = Akismet::http_post(
 			Akismet::build_query(
@@ -253,6 +339,15 @@ class Akismet_REST_API {
 		return current_user_can( 'manage_options' );
 	}
 
+	/**
+	 * For calls that Akismet.com makes to the site to clear outdated alert codes, use the API key for authorization.
+	 */
+	public static function remote_call_permission_callback( $request ) {
+		$local_key = Akismet::get_api_key();
+
+		return $local_key && ( strtolower( $request->get_param( 'key' ) ) === strtolower( $local_key ) );
+	}
+
 	public static function sanitize_interval( $interval, $request, $param ) {
 		$interval = trim( $interval );
 
diff --git a/wp-content/plugins/akismet/class.akismet.php b/wp-content/plugins/akismet/class.akismet.php
index 3a1307f42f158ea8a33a72e4d1a1580ed33a8f50..9b70d9ecf0891cec7a8ba9585bed92f85185cacc 100644
--- a/wp-content/plugins/akismet/class.akismet.php
+++ b/wp-content/plugins/akismet/class.akismet.php
@@ -762,7 +762,6 @@ class Akismet {
 				|| strtotime( $comment->comment_date_gmt ) < strtotime( "-15 days" ) // Comment is too old.
 				|| $comment->comment_approved !== "0" // Comment is no longer in the Pending queue
 				) {
-				echo "Deleting";
 				delete_comment_meta( $comment_id, 'akismet_error' );
 				delete_comment_meta( $comment_id, 'akismet_delayed_moderation_email' );
 				continue;
diff --git a/wp-content/plugins/akismet/readme.txt b/wp-content/plugins/akismet/readme.txt
index 4853f6fa0dbcacea13883e7a06be238c1ef117d7..9473fb95f2dcdece5e4730f38e69d20753412511 100644
--- a/wp-content/plugins/akismet/readme.txt
+++ b/wp-content/plugins/akismet/readme.txt
@@ -2,8 +2,8 @@
 Contributors: matt, ryan, andy, mdawaffe, tellyworth, josephscott, lessbloat, eoigal, cfinke, automattic, jgs, procifer, stephdau
 Tags: akismet, comments, spam, antispam, anti-spam, anti spam, comment moderation, comment spam, contact form spam, spam comments
 Requires at least: 4.0
-Tested up to: 4.9.6
-Stable tag: 4.0.8
+Tested up to: 5.0
+Stable tag: 4.1
 License: GPLv2 or later
 
 Akismet checks your comments and contact form submissions against our global database of spam to protect you and your site from malicious content.
@@ -30,6 +30,13 @@ Upload the Akismet plugin to your blog, Activate it, then enter your [Akismet.co
 
 == Changelog ==
 
+= 4.1 =
+*Release Date - 12 November 2018*
+
+* Added a WP-CLI method for retrieving stats.
+* Hooked into the new "Personal Data Eraser" functionality from WordPress 4.9.6.
+* Added functionality to clear outdated alerts from Akismet.com.
+
 = 4.0.8 =
 *Release Date - 19 June 2018*