diff --git a/.claude/settings.local.json b/.claude/settings.local.json
index bea9a805..df07712a 100755
--- a/.claude/settings.local.json
+++ b/.claude/settings.local.json
@@ -70,7 +70,10 @@
"Bash(git -C /var/www/html add:*)",
"Bash(git -C /var/www/html diff --cached --stat)",
"Bash(git -C /var/www/html commit -m \"$\\(cat <<''EOF''\nAdd 6 reusable page templates with ACF integration\n\nIntroduces layout-focused templates for marketing pages:\n- Content with Sidebar: 70/30 grid with callout boxes\n- Alternating Blocks: Zigzag image/text sections\n- Service Detail: Hero + features grid + FAQ accordion\n- Card Grid: Configurable 2/3/4 column card layouts\n- Long-Form Article: Clean reading layout with related links\n- Landing Page: Conversion-focused with benefits and testimonial\n\nEach template has corresponding ACF field groups for content\nmanagement. Sample pages created under /page-template-examples/.\n\nš¤ Generated with [Claude Code]\\(https://claude.com/claude-code\\)\n\nCo-Authored-By: Claude Opus 4.5 \nEOF\n\\)\")",
- "Bash(cat:*)"
+ "Bash(cat:*)",
+ "Bash(rsync -av /var/www/vhosts/homeprozrealestate.com/httpdocs/wp-content/plugins/mls-by-hansonxyz/includes/class-mls-query.php /var/www/vhosts/homeprozrealestate.com/staging/wp-content/plugins/mls-by-hansonxyz/includes/class-mls-query.php && rsync -av /var/www/vhosts/homeprozrealestate.com/httpdocs/wp-content/plugins/mls-by-hansonxyz/includes/class-mls-cluster.php /var/www/vhosts/homeprozrealestate.com/staging/wp-content/plugins/mls-by-hansonxyz/includes/class-mls-cluster.php)",
+ "Bash(crontab:*)",
+ "Bash(rsync:*)"
],
"deny": [],
"ask": []
diff --git a/.gitignore b/.gitignore
index 5a473d30..af4cdfd7 100755
--- a/.gitignore
+++ b/.gitignore
@@ -29,6 +29,15 @@ Thumbs.db
# Debug
wp-content/debug.log
+wp-content/debug.log.*
+
+# Runtime image caches (regenerable, capped by mls-image-cache-cap)
+wp-content/cache/transformed-images/
+wp-content/uploads/mls-thumbnails/
+wp-content/uploads/mls-listings/
+
+# Local Claude CLI tooling
+node_modules/claude-cli/
# Vite
*.local
diff --git a/CLAUDE.md b/CLAUDE.md
index ed2ed1da..5da1b8f0 100755
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -13,6 +13,18 @@ Custom WordPress theme for HomeProz Real Estate (Albert Lea, MN). Dark/rust bran
7. **No custom animations** - keep it static and fast
8. **ASK before architectural decisions**
9. **No git commits unless asked** - commits are for checkpoints before major work or major milestones, not for small single-file changes
+10. **Sync to staging** - after modifying theme or plugin files, sync them to `/var/www/vhosts/homeprozrealestate.com/staging/` using rsync
+
+## Version Control Policy
+
+Git is a snapshot tool and the historical record of what changed on the site. **If it's not in git, it may as well not exist.**
+
+When asked to commit, commit **everything except build artifacts** ā do not pick a "scope" or hand-select files. The point is the snapshot.
+
+- **Commit:** all source (PHP, SCSS, JS), configs, `package.json`/`package-lock.json`, `db_content_updates/`, `node_modules/`, `dist/`, DB snapshots (`*.sql.gz`), plugins, themes, `CLAUDE.md`. `node_modules/` and `dist/` are tracked intentionally ā see comments in `.gitignore`.
+- **Do not commit:** runtime caches (`wp-content/cache/transformed-images/`), log files (`wp-content/debug.log*`), and other transient/regenerable runtime output. These belong in `.gitignore`.
+
+If you find untracked files in scope of a commit, include them. If something looks ambiguous, default to committing it ā under-tracking loses history; over-tracking is reversible.
## Build
@@ -73,3 +85,23 @@ $url = add_query_arg('property', urlencode($title), home_url('/contact/'));
## Page Classes
`Home_Page`, `Properties_Archive`, `Single_Property`, `About_Page`, `Contact_Page`, `Blog_Archive`, `Single_Post`, `Agents_Archive`, `Single_Agent`, `Search_Page`, `Error_404`
+
+## MLS Property Overrides
+
+### Force a non-HomeProz listing to appear as HomeProz
+
+Some properties (e.g., LandProz listings) may need to appear on the HomeProz site. The `is_homeproz` flag overrides the office name check.
+
+1. Find the property's `listing_key`:
+```bash
+wp --allow-root db query "SELECT listing_key, listing_id, street_name, city, list_office_name, is_homeproz FROM wp_mls_properties WHERE listing_id LIKE '%%'"
+```
+
+2. Set the override flag:
+```bash
+wp --allow-root db query "UPDATE wp_mls_properties SET is_homeproz = 1 WHERE listing_key = ''"
+```
+
+3. Document the change in `db_content_updates/` per the Database Content Changes policy.
+
+**Example**: 121 Main St, Glenville (NST7785198) is listed under "LandProz Real Estate, LLC" but appears on HomeProz via `is_homeproz = 1`.
diff --git a/db_content_updates/2026-01-05_SEO_albert_lea_landing_page.md b/db_content_updates/2026-01-05_SEO_albert_lea_landing_page.md
old mode 100644
new mode 100755
diff --git a/db_content_updates/2026-01-06_agent-testimonials.md b/db_content_updates/2026-01-06_agent-testimonials.md
old mode 100644
new mode 100755
diff --git a/db_content_updates/2026-01-06_favicon-management.md b/db_content_updates/2026-01-06_favicon-management.md
old mode 100644
new mode 100755
diff --git a/db_content_updates/2026-01-06_mls-ssl-skip-config.md b/db_content_updates/2026-01-06_mls-ssl-skip-config.md
old mode 100644
new mode 100755
diff --git a/db_content_updates/2026-01-12_22-37_property-inquiry-form-reorder.md b/db_content_updates/2026-01-12_22-37_property-inquiry-form-reorder.md
new file mode 100755
index 00000000..6c10a124
--- /dev/null
+++ b/db_content_updates/2026-01-12_22-37_property-inquiry-form-reorder.md
@@ -0,0 +1,138 @@
+# Property Inquiry Form Field Reorder
+
+**Date:** 2026-01-12
+**Purpose:** Reorder Contact Form 7 "Property Inquiry Form" fields so Additional Comments appears after Name/Email/Phone
+**Status:** Applied to dev on 2026-01-12
+
+## Background
+
+The property inquiry form should have this field order:
+1. Your Inquiry (readonly display message)
+2. Your Name
+3. Email / Phone (side by side)
+4. Additional Comments
+5. Submit button
+
+Previously, Additional Comments was above the contact fields.
+
+## Changes Required
+
+### Via WP Admin (Recommended)
+
+1. Go to WP Admin > Contact > Forms
+2. Edit "Property Inquiry Form"
+3. Reorder the form fields as shown below
+4. Save the form
+
+### New Form Structure
+
+```
+
+
+ [textarea comments placeholder "Any specific questions or information you'd like to know..."]
+
+
+[submit class:btn class:btn-primary class:btn-lg "Send Inquiry"]
+```
+
+### Via SQL (Alternative)
+
+**Important:** CF7 stores the form structure in `wp_postmeta._form`, not `wp_posts.post_content`.
+
+First, find the form ID:
+```sql
+SELECT ID, post_title FROM wp_posts
+WHERE post_type = 'wpcf7_contact_form'
+AND post_title = 'Property Inquiry Form';
+-- Result: ID = 156 (in dev)
+```
+
+Then update the `_form` meta with the new form structure:
+```sql
+UPDATE wp_postmeta
+SET meta_value = '
The Default (PHP) mailer is currently selected, but is not recommended because in most cases it does not resolve email delivery issues.
Please consider selecting and configuring one of the other mailers.
"
+msgstr ""
+
+#: src/Admin/Area.php:539
+#: src/Admin/PageAbstract.php:192
+msgid "Save Settings"
+msgstr ""
+
+#: src/Admin/Area.php:540
+#: src/Admin/Pages/DebugEventsTab.php:149
+msgid "Cancel"
+msgstr ""
+
+#: src/Admin/Area.php:541
+msgid "Warning icon"
+msgstr ""
+
+#: src/Admin/Area.php:546
+msgid "%name% is a PRO Feature"
+msgstr ""
+
+#: src/Admin/Area.php:547
+msgid "We're sorry, the %name% mailer is not available on your plan. Please upgrade to the PRO plan to unlock all these awesome features."
+msgstr ""
+
+#. Translators: %s - discount value $50.
+#: src/Admin/Area.php:553
+msgid "Bonus: WP Mail SMTP users get %s off regular price, applied at checkout."
+msgstr ""
+
+#: src/Admin/Area.php:567
+#: src/Admin/SetupWizard.php:258
+msgid "Already purchased?"
+msgstr ""
+
+#: src/Admin/Area.php:574
+msgid "Email Rate Limiting is a Pro Feature"
+msgstr ""
+
+#: src/Admin/Area.php:575
+msgid "We're sorry, Email Rate Limiting is not available on your plan. Please upgrade to the Pro plan to unlock all these awesome features."
+msgstr ""
+
+#: src/Admin/Area.php:658
+#: src/Admin/Area.php:666
+#: src/Admin/Pages/AboutTab.php:233
+#: src/Connect.php:55
+msgid "Activate"
+msgstr ""
+
+#: src/Admin/Area.php:660
+#: src/Admin/Pages/AboutTab.php:222
+msgid "Active"
+msgstr ""
+
+#: src/Admin/Area.php:661
+#: src/Admin/Pages/AboutTab.php:230
+msgid "Inactive"
+msgstr ""
+
+#: src/Admin/Area.php:662
+msgid "Processing..."
+msgstr ""
+
+#: src/Admin/Area.php:663
+#: src/Admin/Pages/AboutTab.php:251
+msgid "Visit Site"
+msgstr ""
+
+#: src/Admin/Area.php:664
+msgid "Could not install a plugin. Please download from WordPress.org and install manually."
+msgstr ""
+
+#: src/Admin/Area.php:665
+msgid "Install and Activate"
+msgstr ""
+
+#: src/Admin/Area.php:667
+msgid "Download"
+msgstr ""
+
+#. translators: %1$s - WP.org link; %2$s - same WP.org link.
+#: src/Admin/Area.php:745
+msgid "Please rate WP Mail SMTP★★★★★ on WordPress.org to help us spread the word. Thank you from the WP Mail SMTP team!"
+msgstr ""
+
+#: src/Admin/Area.php:1197
+msgid "WP Mail SMTP Pro related message was successfully dismissed."
+msgstr ""
+
+#: src/Admin/Area.php:1265
+msgid "Educational notice for this mailer was successfully dismissed."
+msgstr ""
+
+#: src/Admin/Area.php:1269
+msgid "Notice was successfully dismissed."
+msgstr ""
+
+#: src/Admin/Area.php:1300
+msgid "Get WP Mail SMTP Pro"
+msgstr ""
+
+#: src/Admin/Area.php:1306
+msgid "Go to WP Mail SMTP Settings page"
+msgstr ""
+
+#: src/Admin/Area.php:1314
+msgid "Go to WPMailSMTP.com documentation page"
+msgstr ""
+
+#: src/Admin/Area.php:1315
+#: src/Admin/Area.php:1499
+msgid "Docs"
+msgstr ""
+
+#: src/Admin/Area.php:1477
+msgid "Made with ā„ by the WP Mail SMTP team"
+msgstr ""
+
+#: src/Admin/Area.php:1488
+msgid "Support"
+msgstr ""
+
+#: src/Admin/Area.php:1507
+msgid "Free Plugins"
+msgstr ""
+
+#: src/Admin/ConnectionSettings.php:85
+msgid "If you're using an email provider (Yahoo, Outlook.com, etc) this should be your email address for that account."
+msgstr ""
+
+#: src/Admin/ConnectionSettings.php:88
+msgid "Please note that other plugins can change this, to prevent this use the setting below."
+msgstr ""
+
+#: src/Admin/ConnectionSettings.php:112
+msgid "Current provider will automatically force From Email to be the email address that you use to set up the OAuth connection below."
+msgstr ""
+
+#: src/Admin/ConnectionSettings.php:116
+msgid "If checked, the From Email setting above will be used for all emails, ignoring values set by other plugins."
+msgstr ""
+
+#: src/Admin/ConnectionSettings.php:163
+msgid "Current provider doesn't support setting and forcing From Name. Emails will be sent on behalf of the account name used to setup the OAuth connection below."
+msgstr ""
+
+#: src/Admin/ConnectionSettings.php:167
+msgid "If checked, the From Name setting above will be used for all emails, ignoring values set by other plugins."
+msgstr ""
+
+#: src/Admin/ConnectionSettings.php:177
+msgid "Return Path"
+msgstr ""
+
+#: src/Admin/ConnectionSettings.php:193
+msgid "Return Path indicates where non-delivery receipts - or bounce messages - are to be sent."
+msgstr ""
+
+#: src/Admin/ConnectionSettings.php:194
+msgid "If unchecked, bounce messages may be lost."
+msgstr ""
+
+#: src/Admin/ConnectionSettings.php:246
+msgid "Don't see what you're looking for?"
+msgstr ""
+
+#: src/Admin/ConnectionSettings.php:251
+msgid "Suggest a Mailer"
+msgstr ""
+
+#: src/Admin/ConnectionSettings.php:279
+msgid "Dismiss this notice"
+msgstr ""
+
+#: src/Admin/DashboardWidget.php:283
+msgid "View Detailed Email Stats"
+msgstr ""
+
+#: src/Admin/DashboardWidget.php:284
+msgid "Automatically keep track of every email sent from your WordPress site and view valuable statistics right here in your dashboard."
+msgstr ""
+
+#: src/Admin/DashboardWidget.php:364
+#: src/Pro/Emails/Logs/Admin/SinglePage.php:263
+msgid "Error icon"
+msgstr ""
+
+#. translators: %d - number of failed emails.
+#: src/Admin/DashboardWidget.php:372
+msgid "We detected %d failed email in the last 30 days."
+msgid_plural "We detected %d failed emails in the last 30 days."
+msgstr[0] ""
+msgstr[1] ""
+
+#. translators: %s - URL to WPMailSMTP.com.
+#: src/Admin/DashboardWidget.php:383
+msgid "Upgrade to Pro and get instant alert notifications when they fail."
+msgstr ""
+
+#: src/Admin/DashboardWidget.php:404
+msgid "Dismiss email alert block"
+msgstr ""
+
+#: src/Admin/DashboardWidget.php:430
+msgid "NEW! Enable Weekly Email Summaries"
+msgstr ""
+
+#: src/Admin/DashboardWidget.php:439
+msgid "View Example"
+msgstr ""
+
+#: src/Admin/DashboardWidget.php:445
+msgid "Weekly Email Summaries have been enabled"
+msgstr ""
+
+#. translators: %s - URL to WPMailSMTP.com.
+#: src/Admin/DashboardWidget.php:468
+msgid "Upgrade to Pro for detailed stats, email logs, and more!"
+msgstr ""
+
+#: src/Admin/DashboardWidget.php:494
+msgid "Select timespan"
+msgstr ""
+
+#: src/Admin/DashboardWidget.php:496
+msgid "All Time"
+msgstr ""
+
+#. translators: %d - Number of days.
+#: src/Admin/DashboardWidget.php:501
+msgid "Last %d day"
+msgid_plural "Last %d days"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/Admin/DashboardWidget.php:517
+msgid "Confirmed Emails"
+msgstr ""
+
+#: src/Admin/DashboardWidget.php:518
+msgid "Unconfirmed Emails"
+msgstr ""
+
+#: src/Admin/DashboardWidget.php:519
+msgid "Failed Emails"
+msgstr ""
+
+#: src/Admin/DashboardWidget.php:524
+msgid "Sent Emails"
+msgstr ""
+
+#: src/Admin/DashboardWidget.php:528
+msgid "Select email type"
+msgstr ""
+
+#: src/Admin/DashboardWidget.php:530
+msgid "All Emails"
+msgstr ""
+
+#: src/Admin/DashboardWidget.php:558
+msgid "Graph Style"
+msgstr ""
+
+#: src/Admin/DashboardWidget.php:562
+msgid "Bar"
+msgstr ""
+
+#: src/Admin/DashboardWidget.php:566
+msgid "Line"
+msgstr ""
+
+#: src/Admin/DashboardWidget.php:571
+msgid "Color Scheme"
+msgstr ""
+
+#: src/Admin/DashboardWidget.php:579
+msgid "WordPress"
+msgstr ""
+
+#: src/Admin/DashboardWidget.php:583
+msgid "Save Changes"
+msgstr ""
+
+#: src/Admin/DashboardWidget.php:628
+msgid "Table cell icon"
+msgstr ""
+
+#. translators: %d number of total emails sent.
+#: src/Admin/DashboardWidget.php:659
+msgid "%d total"
+msgstr ""
+
+#. translators: %s fixed string of 'N/A'.
+#: src/Admin/DashboardWidget.php:665
+msgid "Confirmed %s"
+msgstr ""
+
+#. translators: %s fixed string of 'N/A'.
+#: src/Admin/DashboardWidget.php:671
+msgid "Unconfirmed %s"
+msgstr ""
+
+#. translators: %s fixed string of 'N/A'.
+#: src/Admin/DashboardWidget.php:677
+msgid "Failed %s"
+msgstr ""
+
+#. translators: %s fixed string of 'N/A'.
+#: src/Admin/DashboardWidget.php:688
+msgid "Sent %s"
+msgstr ""
+
+#: src/Admin/DebugEvents/DebugEvents.php:100
+#: src/Admin/DebugEvents/DebugEvents.php:143
+msgid "Access rejected."
+msgstr ""
+
+#: src/Admin/DebugEvents/DebugEvents.php:104
+#: src/Admin/DebugEvents/DebugEvents.php:147
+#: src/Admin/Pages/DebugEventsTab.php:365
+msgid "You don't have the capability to perform this action."
+msgstr ""
+
+#: src/Admin/DebugEvents/DebugEvents.php:108
+#: src/Admin/DebugEvents/DebugEvents.php:151
+msgid "For some reason the database table was not installed correctly. Please contact plugin support team to diagnose and fix the issue."
+msgstr ""
+
+#: src/Admin/DebugEvents/DebugEvents.php:121
+msgid "All debug event entries were deleted successfully."
+msgstr ""
+
+#. translators: %s - WPDB error message.
+#: src/Admin/DebugEvents/DebugEvents.php:126
+msgid "There was an issue while trying to delete all debug event entries. Error message: %s"
+msgstr ""
+
+#: src/Admin/DebugEvents/DebugEvents.php:157
+msgid "No Debug Event ID provided!"
+msgstr ""
+
+#: src/Admin/DebugEvents/DebugEvents.php:343
+msgid "Number of events per page:"
+msgstr ""
+
+#. translators: %d the event ID.
+#: src/Admin/DebugEvents/Event.php:147
+msgid "Event #%d"
+msgstr ""
+
+#: src/Admin/DebugEvents/Event.php:184
+#: src/Providers/PepipostAPI/Mailer.php:342
+msgid "Error"
+msgstr ""
+
+#: src/Admin/DebugEvents/Event.php:185
+#: src/SiteHealth.php:141
+msgid "Debug"
+msgstr ""
+
+#: src/Admin/DebugEvents/Event.php:244
+#: src/WP.php:604
+msgid "N/A"
+msgstr ""
+
+#: src/Admin/DebugEvents/Event.php:357
+msgid "Debug Event Details"
+msgstr ""
+
+#: src/Admin/DebugEvents/Event.php:360
+#: src/Admin/DebugEvents/Table.php:170
+msgid "Type"
+msgstr ""
+
+#: src/Admin/DebugEvents/Event.php:364
+#: src/Admin/DebugEvents/Table.php:173
+msgid "Date"
+msgstr ""
+
+#: src/Admin/DebugEvents/Event.php:368
+#: src/Admin/DebugEvents/Table.php:171
+msgid "Content"
+msgstr ""
+
+#: src/Admin/DebugEvents/Event.php:375
+#: src/Admin/DebugEvents/Table.php:172
+#: src/Admin/Pages/ExportTab.php:128
+msgid "Source"
+msgstr ""
+
+#. Translators: %1$s the path of a file, %2$s the line number in the file.
+#: src/Admin/DebugEvents/Event.php:381
+msgid "%1$s (line: %2$s)"
+msgstr ""
+
+#: src/Admin/DebugEvents/Event.php:389
+msgid "Backtrace:"
+msgstr ""
+
+#. translators: %1$d - index number; %2$s - function name; %3$s - file path; %4$s - line number.
+#: src/Admin/DebugEvents/Event.php:395
+msgid "[%1$d] %2$s called at [%3$s:%4$s]"
+msgstr ""
+
+#. Translators: %s - Email initiator/source name.
+#: src/Admin/DebugEvents/Event.php:429
+msgid "Email Source: %s"
+msgstr ""
+
+#: src/Admin/DebugEvents/Table.php:115
+msgid "All"
+msgstr ""
+
+#: src/Admin/DebugEvents/Table.php:169
+msgid "Event"
+msgstr ""
+
+#: src/Admin/DebugEvents/Table.php:489
+msgid "No events found."
+msgstr ""
+
+#: src/Admin/DebugEvents/Table.php:491
+msgid "No events have been logged for now."
+msgstr ""
+
+#: src/Admin/DebugEvents/Table.php:552
+#: src/Admin/Pages/ExportTab.php:133
+msgid "Select a date range"
+msgstr ""
+
+#: src/Admin/DebugEvents/Table.php:556
+msgid "Filter"
+msgstr ""
+
+#: src/Admin/DebugEvents/Table.php:565
+msgid "Delete All Events"
+msgstr ""
+
+#: src/Admin/DomainChecker.php:70
+msgid "Something went wrong. Please try again later."
+msgstr ""
+
+#: src/Admin/DomainChecker.php:178
+msgid "Domain Check Results"
+msgstr ""
+
+#. translators: %s - item state name.
+#: src/Admin/DomainChecker.php:190
+msgid "%s icon"
+msgstr ""
+
+#. translators: %s - WPMailSMTP.com Upgrade page URL.
+#: src/Admin/Education.php:73
+msgid "Youāre using WP Mail SMTP Lite. To unlock more features, consider upgrading to Pro for %2$s OFF."
+msgstr ""
+
+#: src/Admin/Education.php:86
+msgid "Dismiss this message."
+msgstr ""
+
+#: src/Admin/FlyoutMenu.php:52
+msgid "See Quick Links"
+msgstr ""
+
+#: src/Admin/FlyoutMenu.php:107
+msgid "Support & Docs"
+msgstr ""
+
+#: src/Admin/FlyoutMenu.php:113
+msgid "Follow on Facebook"
+msgstr ""
+
+#: src/Admin/FlyoutMenu.php:118
+msgid "Suggest a Feature"
+msgstr ""
+
+#: src/Admin/Notifications.php:481
+msgid "Notifications"
+msgstr ""
+
+#: src/Admin/Notifications.php:485
+msgid "Dismiss this message"
+msgstr ""
+
+#: src/Admin/Notifications.php:490
+msgid "Previous message"
+msgstr ""
+
+#: src/Admin/Notifications.php:494
+msgid "Next message"
+msgstr ""
+
+#: src/Admin/Pages/About.php:50
+#: src/Admin/Pages/AboutTab.php:44
+msgid "About Us"
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:71
+msgid "Hello and welcome to WP Mail SMTP, the easiest and most popular WordPress SMTP plugin. We build software that helps your site reliably deliver emails every time."
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:75
+msgid "Email deliverability has been a well-documented problem for all WordPress websites. However as WPForms grew, we became more aware of this painful issue that affects our users and the larger WordPress community. So we decided to solve this problem and make a solution that's beginner friendly."
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:78
+msgid "Our goal is to make reliable email deliverability easy for WordPress."
+msgstr ""
+
+#. translators: %1$s - WPForms URL, %2$s - WPBeginner URL, %3$s - OptinMonster URL, %4$s - MonsterInsights URL, %5$s - Awesome Motive URL
+#: src/Admin/Pages/AboutTab.php:85
+msgid "WP Mail SMTP is brought to you by the same team that's behind the most user friendly WordPress forms, WPForms, the largest WordPress resource site, WPBeginner, the most popular lead-generation software, OptinMonster, the best WordPress analytics plugin, MonsterInsights, and more."
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:104
+msgid "Yup, we know a thing or two about building awesome products that customers love."
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:110
+msgid "The WPForms Team photo"
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:112
+msgid "The WPForms Team"
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:161
+msgid "Plugin icon"
+msgstr ""
+
+#. translators: %s - status HTML text.
+#: src/Admin/Pages/AboutTab.php:175
+msgid "Status: %s"
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:241
+msgid "Not Installed"
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:244
+msgid "Install Plugin"
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:272
+msgid "OptinMonster"
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:273
+msgid "Instantly get more subscribers, leads, and sales with the #1 conversion optimization toolkit. Create high converting popups, announcement bars, spin a wheel, and more with smart targeting and personalization."
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:279
+#: src/Admin/Pages/SmartRoutingTab.php:278
+msgid "WPForms"
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:280
+#: src/Admin/Pages/AboutTab.php:286
+msgid "The best drag & drop WordPress form builder. Easily create beautiful contact forms, surveys, payment forms, and more with our 600+ form templates. Trusted by over 5 million websites as the best forms plugin."
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:285
+msgid "WPForms Pro"
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:293
+msgid "MonsterInsights"
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:294
+#: src/Admin/Pages/AboutTab.php:300
+msgid "The leading WordPress analytics plugin that shows you how people find and use your website, so you can make data driven decisions to grow your business. Properly set up Google Analytics without writing code."
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:299
+msgid "MonsterInsights Pro"
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:307
+#: src/Admin/Pages/AboutTab.php:313
+msgid "AIOSEO"
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:308
+#: src/Admin/Pages/AboutTab.php:314
+msgid "The original WordPress SEO plugin and toolkit that improves your websiteās search rankings. Comes with all the SEO features like Local SEO, WooCommerce SEO, sitemaps, SEO optimizer, schema, and more."
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:321
+#: src/Admin/Pages/AboutTab.php:327
+msgid "SeedProd"
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:322
+#: src/Admin/Pages/AboutTab.php:328
+msgid "The fastest drag & drop landing page builder for WordPress. Create custom landing pages without writing code, connect them with your CRM, collect subscribers, and grow your audience. Trusted by 1 million sites."
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:335
+msgid "RafflePress"
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:336
+#: src/Admin/Pages/AboutTab.php:342
+msgid "Turn your website visitors into brand ambassadors! Easily grow your email list, website traffic, and social media followers with the most powerful giveaways & contests plugin for WordPress."
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:341
+msgid "RafflePress Pro"
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:349
+msgid "PushEngage"
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:350
+msgid "Connect with your visitors after they leave your website with the leading web push notification software. Over 10,000+ businesses worldwide use PushEngage to send 15 billion notifications each month."
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:356
+#: src/Admin/Pages/AboutTab.php:362
+msgid "Smash Balloon Instagram Feeds"
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:357
+#: src/Admin/Pages/AboutTab.php:363
+msgid "Easily display Instagram content on your WordPress site without writing any code. Comes with multiple templates, ability to show content from multiple accounts, hashtags, and more. Trusted by 1 million websites."
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:370
+#: src/Admin/Pages/AboutTab.php:376
+msgid "Smash Balloon Facebook Feeds"
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:371
+#: src/Admin/Pages/AboutTab.php:377
+msgid "Easily display Facebook content on your WordPress site without writing any code. Comes with multiple templates, ability to embed albums, group content, reviews, live videos, comments, and reactions."
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:384
+#: src/Admin/Pages/AboutTab.php:390
+msgid "Smash Balloon YouTube Feeds"
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:385
+#: src/Admin/Pages/AboutTab.php:391
+msgid "Easily display YouTube videos on your WordPress site without writing any code. Comes with multiple layouts, ability to embed live streams, video filtering, ability to combine multiple channel videos, and more."
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:398
+#: src/Admin/Pages/AboutTab.php:404
+msgid "Smash Balloon Twitter Feeds"
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:399
+#: src/Admin/Pages/AboutTab.php:405
+msgid "Easily display Twitter content in WordPress without writing any code. Comes with multiple layouts, ability to combine multiple Twitter feeds, Twitter card support, tweet moderation, and more."
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:412
+msgid "TrustPulse"
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:413
+msgid "Boost your sales and conversions by up to 15% with real-time social proof notifications. TrustPulse helps you show live user activity and purchases to help convince other users to purchase."
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:419
+#: src/Admin/Pages/AboutTab.php:425
+msgid "SearchWP"
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:420
+#: src/Admin/Pages/AboutTab.php:426
+msgid "The most advanced WordPress search plugin. Customize your WordPress search algorithm, reorder search results, track search metrics, and everything you need to leverage search to grow your business."
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:433
+#: src/Admin/Pages/AboutTab.php:439
+msgid "AffiliateWP"
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:434
+#: src/Admin/Pages/AboutTab.php:440
+msgid "The #1 affiliate management plugin for WordPress. Easily create an affiliate program for your eCommerce store or membership site within minutes and start growing your sales with the power of referral marketing."
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:447
+msgid "WP Simple Pay"
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:448
+#: src/Admin/Pages/AboutTab.php:454
+msgid "The #1 Stripe payments plugin for WordPress. Start accepting one-time and recurring payments on your WordPress site without setting up a shopping cart. No code required."
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:453
+msgid "WP Simple Pay Pro"
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:461
+msgid "Easy Digital Downloads"
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:462
+msgid "The best WordPress eCommerce plugin for selling digital downloads. Start selling eBooks, software, music, digital art, and more within minutes. Accept payments, manage subscriptions, advanced access control, and more."
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:468
+msgid "Sugar Calendar Lite"
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:469
+#: src/Admin/Pages/AboutTab.php:475
+msgid "A simple & powerful event calendar plugin for WordPress that comes with all the event management features including payments, scheduling, timezones, ticketing, recurring events, and more."
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:474
+msgid "Sugar Calendar"
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:482
+msgid "Charitable"
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:483
+msgid "Top-rated WordPress donation and fundraising plugin. Over 10,000+ non-profit organizations and website owners use Charitable to create fundraising campaigns and raise more money online."
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:489
+msgid "WPCode Lite"
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:490
+#: src/Admin/Pages/AboutTab.php:496
+msgid "Future proof your WordPress customizations with the most popular code snippet management plugin for WordPress. Trusted by over 1,500,000+ websites for easily adding code to WordPress right from the admin area."
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:495
+msgid "WPCode Pro"
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:503
+msgid "Duplicator"
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:504
+#: src/Admin/Pages/AboutTab.php:510
+msgid "Leading WordPress backup & site migration plugin. Over 1,500,000+ smart website owners use Duplicator to make reliable and secure WordPress backups to protect their websites. It also makes website migration really easy."
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:509
+msgid "Duplicator Pro"
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:529
+msgid "Could not activate the plugin. Please activate it from the Plugins page."
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:555
+msgid "Could not activate the plugin. Plugin is not whitelisted."
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:561
+msgid "Plugin activated."
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:577
+msgid "Could not install the plugin."
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:591
+#: src/Admin/SetupWizard.php:872
+msgid "Could not install the plugin. Plugin is not whitelisted."
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:658
+#: src/Connect.php:210
+#: src/Connect.php:218
+#: src/Connect.php:298
+msgid "Plugin installed & activated."
+msgstr ""
+
+#: src/Admin/Pages/AboutTab.php:666
+msgid "Plugin installed."
+msgstr ""
+
+#: src/Admin/Pages/ActionSchedulerTab.php:41
+#: src/Admin/Pages/ActionSchedulerTab.php:101
+msgid "Scheduled Actions"
+msgstr ""
+
+#. translators: %s - Action Scheduler website URL.
+#: src/Admin/Pages/ActionSchedulerTab.php:107
+msgid "WP Mail SMTP is using the Action Scheduler library, which allows it to queue and process bigger tasks in the background without making your site slower for your visitors. Below you can see the list of all tasks and their status. This table can be very useful when debugging certain issues."
+msgstr ""
+
+#: src/Admin/Pages/ActionSchedulerTab.php:122
+msgid "Action Scheduler library is also used by other plugins, like WPForms and WooCommerce, so you might see tasks that are not related to our plugin in the table below."
+msgstr ""
+
+#. translators: %s - search term.
+#: src/Admin/Pages/ActionSchedulerTab.php:130
+msgid "Search results for %s"
+msgstr ""
+
+#: src/Admin/Pages/AdditionalConnectionsTab.php:49
+#: src/Admin/Pages/AdditionalConnectionsTab.php:106
+msgid "Additional Connections"
+msgstr ""
+
+#: src/Admin/Pages/AdditionalConnectionsTab.php:110
+msgid "Create additional connections to set a backup for your Primary Connection or to configure Smart Routing."
+msgstr ""
+
+#: src/Admin/Pages/AdditionalConnectionsTab.php:143
+#: src/Admin/Pages/SettingsTab.php:337
+#: src/Admin/Pages/SettingsTab.php:361
+msgid "Backup Connection"
+msgstr ""
+
+#: src/Admin/Pages/AdditionalConnectionsTab.php:148
+#: src/Admin/Pages/SmartRoutingTab.php:51
+#: src/Admin/Pages/SmartRoutingTab.php:102
+msgid "Smart Routing"
+msgstr ""
+
+#: src/Admin/Pages/AdditionalConnectionsTab.php:177
+msgid "With additional connections you can..."
+msgstr ""
+
+#: src/Admin/Pages/AdditionalConnectionsTab.php:180
+msgid "Set a Backup Connection"
+msgstr ""
+
+#: src/Admin/Pages/AdditionalConnectionsTab.php:183
+msgid "Use mailers for different purposes"
+msgstr ""
+
+#: src/Admin/Pages/AdditionalConnectionsTab.php:186
+msgid "Create advanced routing rules"
+msgstr ""
+
+#: src/Admin/Pages/AlertsTab.php:43
+#: src/Admin/Pages/AlertsTab.php:81
+msgid "Alerts"
+msgstr ""
+
+#: src/Admin/Pages/AlertsTab.php:85
+msgid "Configure at least one of these integrations to receive notifications when email fails to send from your site. Alert notifications will contain the following important data: email subject, email Send To address, the error message, and helpful links to help you fix the issue."
+msgstr ""
+
+#: src/Admin/Pages/AlertsTab.php:98
+msgid "Notify when"
+msgstr ""
+
+#: src/Admin/Pages/AlertsTab.php:105
+msgid "The initial email sending request fails"
+msgstr ""
+
+#: src/Admin/Pages/AlertsTab.php:112
+msgid "This option is always enabled and will notify you about instant email sending failures."
+msgstr ""
+
+#: src/Admin/Pages/AlertsTab.php:119
+msgid "The deliverability verification process detects a hard bounce"
+msgstr ""
+
+#: src/Admin/Pages/AlertsTab.php:125
+msgid "Get notified about emails that were successfully sent, but have hard bounced on delivery attempt. A hard bounce is an email that has failed to deliver for permanent reasons, such as the recipient's email address being invalid."
+msgstr ""
+
+#: src/Admin/Pages/AlertsTab.php:135
+msgid "Email"
+msgstr ""
+
+#: src/Admin/Pages/AlertsTab.php:136
+msgid "Enter the email addresses (3 max) youād like to use to receive alerts when email sending fails. Read our documentation on setting up email alerts."
+msgstr ""
+
+#: src/Admin/Pages/AlertsTab.php:141
+msgid "Email Alerts"
+msgstr ""
+
+#: src/Admin/Pages/AlertsTab.php:153
+#: src/Admin/Pages/TestTab.php:158
+msgid "Send To"
+msgstr ""
+
+#: src/Admin/Pages/AlertsTab.php:164
+msgid "Slack"
+msgstr ""
+
+#: src/Admin/Pages/AlertsTab.php:165
+msgid "Paste in the Slack webhook URL youād like to use to receive alerts when email sending fails. Read our documentation on setting up Slack alerts."
+msgstr ""
+
+#: src/Admin/Pages/AlertsTab.php:170
+msgid "Slack Alerts"
+msgstr ""
+
+#: src/Admin/Pages/AlertsTab.php:182
+#: src/Admin/Pages/AlertsTab.php:211
+#: src/Admin/Pages/AlertsTab.php:240
+#: src/Admin/Pages/AlertsTab.php:316
+msgid "Webhook URL"
+msgstr ""
+
+#: src/Admin/Pages/AlertsTab.php:193
+msgid "Discord"
+msgstr ""
+
+#: src/Admin/Pages/AlertsTab.php:194
+msgid "Paste in the Discord webhook URL youād like to use to receive alerts when email sending fails. Read our documentation on setting up Discord alerts."
+msgstr ""
+
+#: src/Admin/Pages/AlertsTab.php:199
+msgid "Discord Alerts"
+msgstr ""
+
+#: src/Admin/Pages/AlertsTab.php:222
+msgid "Microsoft Teams"
+msgstr ""
+
+#: src/Admin/Pages/AlertsTab.php:223
+msgid "Paste in the Microsoft Teams webhook URL youād like to use to receive alerts when email sending fails. Read our documentation on setting up Microsoft Teams alerts."
+msgstr ""
+
+#: src/Admin/Pages/AlertsTab.php:228
+msgid "Microsoft Teams Alerts"
+msgstr ""
+
+#: src/Admin/Pages/AlertsTab.php:251
+msgid "SMS via Twilio"
+msgstr ""
+
+#: src/Admin/Pages/AlertsTab.php:252
+msgid "To receive SMS alerts, youāll need a Twilio account. Read our documentation to learn how to set up Twilio SMS, then enter your connection details below."
+msgstr ""
+
+#: src/Admin/Pages/AlertsTab.php:257
+msgid "SMS via Twilio Alerts"
+msgstr ""
+
+#: src/Admin/Pages/AlertsTab.php:269
+msgid "Twilio Account ID"
+msgstr ""
+
+#: src/Admin/Pages/AlertsTab.php:275
+msgid "Twilio Auth Token"
+msgstr ""
+
+#: src/Admin/Pages/AlertsTab.php:281
+msgid "From Phone Number"
+msgstr ""
+
+#: src/Admin/Pages/AlertsTab.php:287
+#: src/Admin/Pages/AlertsTab.php:392
+msgid "To Phone Number"
+msgstr ""
+
+#: src/Admin/Pages/AlertsTab.php:298
+msgid "Webhook"
+msgstr ""
+
+#: src/Admin/Pages/AlertsTab.php:299
+msgid "Paste in the webhook URL youād like to use to receive alerts when email sending fails. Read our documentation on setting up webhook alerts."
+msgstr ""
+
+#: src/Admin/Pages/AlertsTab.php:304
+msgid "Webhook Alerts"
+msgstr ""
+
+#: src/Admin/Pages/AlertsTab.php:327
+msgid "Push Notifications"
+msgstr ""
+
+#: src/Admin/Pages/AlertsTab.php:328
+msgid "To receive push notifications on this device, you'll need to allow our plugin to send notifications via this browser. Read our documentation on setting up Push Notification alerts."
+msgstr ""
+
+#: src/Admin/Pages/AlertsTab.php:333
+msgid "Push Notification Alerts"
+msgstr ""
+
+#: src/Admin/Pages/AlertsTab.php:345
+msgid "Connection Name"
+msgstr ""
+
+#: src/Admin/Pages/AlertsTab.php:356
+msgid "WhatsApp"
+msgstr ""
+
+#: src/Admin/Pages/AlertsTab.php:357
+msgid "Enter your WhatsApp Cloud API credentials to receive alerts when email sending fails. You'll need to create a Meta developer account and set up WhatsApp Business Platform."
+msgstr ""
+
+#: src/Admin/Pages/AlertsTab.php:362
+msgid "WhatsApp Alerts"
+msgstr ""
+
+#: src/Admin/Pages/AlertsTab.php:374
+msgid "Access Token"
+msgstr ""
+
+#: src/Admin/Pages/AlertsTab.php:380
+msgid "WhatsApp Business Account ID"
+msgstr ""
+
+#: src/Admin/Pages/AlertsTab.php:386
+msgid "Phone Number ID"
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:35
+#: src/Admin/Pages/ControlTab.php:237
+#: src/Admin/Pages/VersusTab.php:177
+msgid "Email Controls"
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:63
+msgid "Comments"
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:66
+msgid "Awaiting Moderation"
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:67
+msgid "Comment is awaiting moderation. Sent to the site admin and post author if they can edit comments."
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:70
+msgid "Published"
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:71
+msgid "Comment has been published. Sent to the post author."
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:76
+msgid "Change of Admin Email"
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:79
+msgid "Site Admin Email Change Attempt"
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:80
+msgid "Change of site admin email address was attempted. Sent to the proposed new email address."
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:83
+msgid "Site Admin Email Changed"
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:84
+msgid "Site admin email address was changed. Sent to the old site admin email address."
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:87
+msgid "Network Admin Email Change Attempt"
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:88
+msgid "Change of network admin email address was attempted. Sent to the proposed new email address."
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:91
+msgid "Network Admin Email Changed"
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:92
+msgid "Network admin email address was changed. Sent to the old network admin email address."
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:97
+msgid "Change of User Email or Password"
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:100
+msgid "Reset Password Request"
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:101
+msgid "User requested a password reset via \"Lost your password?\". Sent to the user."
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:104
+msgid "Password Reset Successfully"
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:105
+msgid "User reset their password from the password reset link. Sent to the site admin."
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:108
+msgid "Password Changed"
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:109
+msgid "User changed their password. Sent to the user."
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:112
+msgid "Email Change Attempt"
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:113
+msgid "User attempted to change their email address. Sent to the proposed new email address."
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:116
+msgid "Email Changed"
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:117
+msgid "User changed their email address. Sent to the user."
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:122
+msgid "Personal Data Requests"
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:125
+msgid "User Confirmed Export / Erasure Request"
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:126
+msgid "User clicked a confirmation link in personal data export or erasure request email. Sent to the site or network admin."
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:129
+msgid "Admin Erased Data"
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:130
+msgid "Site admin clicked \"Erase Personal Data\" button next to a confirmed data erasure request. Sent to the requester email address."
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:133
+msgid "Admin Sent Link to Export Data"
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:134
+msgid "Site admin clicked \"Email Data\" button next to a confirmed data export request. Sent to the requester email address."
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:135
+msgid "Disabling this option will block users from being able to export their personal data, as they will not receive an email with a link."
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:140
+msgid "Automatic Updates"
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:143
+msgid "Plugin Status"
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:144
+msgid "Completion or failure of a background automatic plugin update. Sent to the site or network admin."
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:147
+msgid "Theme Status"
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:148
+msgid "Completion or failure of a background automatic theme update. Sent to the site or network admin."
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:151
+msgid "WP Core Status"
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:152
+msgid "Completion or failure of a background automatic core update. Sent to the site or network admin."
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:155
+msgid "Full Log"
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:156
+msgid "Full log of background update results which includes information about WordPress core, plugins, themes, and translations updates. Only sent when you are using a development version of WordPress. Sent to the site or network admin."
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:161
+msgid "New User"
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:164
+msgid "Created (Admin)"
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:165
+msgid "A new user was created. Sent to the site admin."
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:168
+msgid "Created (User)"
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:169
+msgid "A new user was created. Sent to the new user."
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:172
+msgid "Invited To Site"
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:173
+msgid "A new user was invited to a site from Users -> Add New -> Add New User. Sent to the invited user."
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:176
+msgid "Created On Site"
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:177
+msgid "A new user account was created. Sent to Network Admin."
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:180
+msgid "Added / Activated on Site"
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:181
+msgid "A user has been added, or their account activation has been successful. Sent to the user, that has been added/activated."
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:186
+msgid "New Site"
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:189
+msgid "User Created Site"
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:190
+msgid "User registered for a new site. Sent to the site admin."
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:193
+msgid "Network Admin: User Activated / Added Site"
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:194
+msgid "User activated their new site, or site was added from Network Admin -> Sites -> Add New. Sent to Network Admin."
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:197
+msgid "Site Admin: Activated / Added Site"
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:198
+msgid "User activated their new site, or site was added from Network Admin -> Sites -> Add New. Sent to Site Admin."
+msgstr ""
+
+#: src/Admin/Pages/ControlTab.php:241
+msgid "Email controls allow you to manage the automatic notifications you receive from your WordPress website. With the flick of a switch, you can reduce inbox clutter and focus on the alerts that matter the most. It's easy to disable emails about comments, email or password changes, WordPress updates, user registrations, and personal data requests."
+msgstr ""
+
+#: src/Admin/Pages/DebugEventsTab.php:84
+#: src/Admin/Pages/DebugEventsTab.php:188
+#: src/Admin/Pages/DebugEventsTab.php:201
+msgid "Debug Events"
+msgstr ""
+
+#: src/Admin/Pages/DebugEventsTab.php:148
+msgid "Are you sure you want to permanently delete all debug events?"
+msgstr ""
+
+#: src/Admin/Pages/DebugEventsTab.php:150
+#: src/Admin/Pages/SettingsTab.php:239
+msgid "Close"
+msgstr ""
+
+#: src/Admin/Pages/DebugEventsTab.php:151
+#: src/Admin/Review.php:139
+msgid "Yes"
+msgstr ""
+
+#: src/Admin/Pages/DebugEventsTab.php:154
+msgid "An error occurred!"
+msgstr ""
+
+#: src/Admin/Pages/DebugEventsTab.php:191
+msgid "On this page, you can view different plugin debugging events and email sending errors."
+msgstr ""
+
+#: src/Admin/Pages/DebugEventsTab.php:204
+msgid "On this page, you can view and configure different plugin debugging events. View email sending errors and enable debugging events, allowing you to detect email sending issues."
+msgstr ""
+
+#: src/Admin/Pages/DebugEventsTab.php:212
+msgid "Event Types"
+msgstr ""
+
+#: src/Admin/Pages/DebugEventsTab.php:228
+msgid "Email Sending Errors"
+msgstr ""
+
+#: src/Admin/Pages/DebugEventsTab.php:231
+msgid "This debug event is always enabled and will record any email sending errors in the table below."
+msgstr ""
+
+#: src/Admin/Pages/DebugEventsTab.php:245
+msgid "Debug Email Sending"
+msgstr ""
+
+#: src/Admin/Pages/DebugEventsTab.php:248
+msgid "Check this if you would like to debug the email sending process. Once enabled, all debug events will be logged in the table below. This setting should only be enabled for shorter debugging periods and disabled afterwards."
+msgstr ""
+
+#: src/Admin/Pages/DebugEventsTab.php:256
+msgid "Events Retention Period"
+msgstr ""
+
+#: src/Admin/Pages/DebugEventsTab.php:262
+msgid "Forever"
+msgstr ""
+
+#: src/Admin/Pages/DebugEventsTab.php:271
+msgid "Debug events older than the selected period will be permanently deleted from the database."
+msgstr ""
+
+#. translators: %1$s - number of debug events found; %2$s - filtered type.
+#: src/Admin/Pages/DebugEventsTab.php:312
+msgid "Found %1$s %2$s event"
+msgid_plural "Found %1$s %2$s events"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/Admin/Pages/DebugEventsTab.php:341
+msgid "Search Events"
+msgstr ""
+
+#: src/Admin/Pages/DebugEventsTab.php:377
+#: src/Admin/Pages/MiscTab.php:539
+#: src/Admin/Pages/SettingsTab.php:437
+msgid "Settings were successfully saved."
+msgstr ""
+
+#. translators: %s The searched term.
+#: src/Admin/Pages/DebugEventsTab.php:416
+msgid "where event contains \"%s\""
+msgstr ""
+
+#. translators: %s - Date.
+#: src/Admin/Pages/DebugEventsTab.php:449
+msgid "on %s"
+msgstr ""
+
+#. translators: %1$s - Date. %2$s - Date.
+#: src/Admin/Pages/DebugEventsTab.php:455
+msgid "between %1$s and %2$s"
+msgstr ""
+
+#: src/Admin/Pages/DebugEventsTab.php:494
+msgid "Debug Events are Not Installed Correctly"
+msgstr ""
+
+#. translators: %1$s - create missing tables link; %2$s - contact support link.
+#: src/Admin/Pages/DebugEventsTab.php:501
+msgid "WP Mail SMTP is using custom database tables for some of its features. In order to work properly, the custom tables should be created, and it seems they are missing. Please try to create the missing DB tables by clicking on this link. If this issue persists, please contact our support and provide the error message below:"
+msgstr ""
+
+#. translators: %1$s - create missing tables link; %2$s - contact support link.
+#: src/Admin/Pages/DebugEventsTab.php:518
+msgid "WP Mail SMTP is using custom database tables for some of its features. In order to work properly, the custom tables should be created, and it seems they are missing. Please try to create the missing DB tables by clicking on this link. If this issue persists, please contact our support."
+msgstr ""
+
+#: src/Admin/Pages/DebugEventsTab.php:567
+msgid "1 Week"
+msgstr ""
+
+#: src/Admin/Pages/DebugEventsTab.php:568
+msgid "1 Month"
+msgstr ""
+
+#: src/Admin/Pages/DebugEventsTab.php:569
+msgid "3 Months"
+msgstr ""
+
+#: src/Admin/Pages/DebugEventsTab.php:570
+msgid "6 Months"
+msgstr ""
+
+#: src/Admin/Pages/DebugEventsTab.php:571
+msgid "1 Year"
+msgstr ""
+
+#. translators: %d - days count.
+#: src/Admin/Pages/DebugEventsTab.php:585
+msgid "%d Day"
+msgid_plural "%d Days"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/Admin/Pages/EmailReports.php:41
+#: src/Admin/Pages/EmailReportsTab.php:42
+#: src/Admin/Pages/SettingsTab.php:231
+msgid "Email Reports"
+msgstr ""
+
+#: src/Admin/Pages/EmailReportsTab.php:114
+msgid "Stats at a Glance"
+msgstr ""
+
+#: src/Admin/Pages/EmailReportsTab.php:119
+msgid "Detailed Stats by Subject Line"
+msgstr ""
+
+#: src/Admin/Pages/EmailReportsTab.php:124
+msgid "Weekly Email Report"
+msgstr ""
+
+#: src/Admin/Pages/EmailReportsTab.php:132
+msgid "Email reports make it easy to track deliverability and engagement at-a-glance. Your open and click-through rates are grouped by subject line, making it easy to review the performance of campaigns or notifications. The report also displays Sent and Failed emails each week so you spot any issues quickly. When you upgrade, we'll also add an email report chart right in your WordPress dashboard."
+msgstr ""
+
+#: src/Admin/Pages/EmailReportsTab.php:156
+msgid "Unlock these awesome reporting features:"
+msgstr ""
+
+#: src/Admin/Pages/EmailReportsTab.php:159
+msgid "Get weekly deliverability reports"
+msgstr ""
+
+#: src/Admin/Pages/EmailReportsTab.php:160
+msgid "View stats grouped by subject line"
+msgstr ""
+
+#: src/Admin/Pages/EmailReportsTab.php:163
+msgid "Track total emails sent each week"
+msgstr ""
+
+#: src/Admin/Pages/EmailReportsTab.php:164
+msgid "Measure open rate and click through rates"
+msgstr ""
+
+#: src/Admin/Pages/EmailReportsTab.php:167
+msgid "Spot failed emails quickly"
+msgstr ""
+
+#: src/Admin/Pages/EmailReportsTab.php:168
+msgid "See email report graphs in WordPress"
+msgstr ""
+
+#: src/Admin/Pages/ExportTab.php:42
+msgid "Export"
+msgstr ""
+
+#: src/Admin/Pages/ExportTab.php:80
+msgid "Export Email Logs"
+msgstr ""
+
+#: src/Admin/Pages/ExportTab.php:84
+msgid "Easily export your logs to CSV or Excel. Filter the logs before you export and only download the data you need. This feature lets you easily create your own deliverability reports. You can also use the data in 3rd party dashboards to track deliverability along with your other website statistics."
+msgstr ""
+
+#: src/Admin/Pages/ExportTab.php:95
+msgid "Export Type"
+msgstr ""
+
+#: src/Admin/Pages/ExportTab.php:97
+msgid "Export in CSV (.csv)"
+msgstr ""
+
+#: src/Admin/Pages/ExportTab.php:100
+msgid "Export in Microsoft Excel (.xlsx)"
+msgstr ""
+
+#: src/Admin/Pages/ExportTab.php:103
+msgid "Export in EML (.eml)"
+msgstr ""
+
+#: src/Admin/Pages/ExportTab.php:108
+msgid "Common Information"
+msgstr ""
+
+#: src/Admin/Pages/ExportTab.php:109
+msgid "To Address"
+msgstr ""
+
+#: src/Admin/Pages/ExportTab.php:110
+msgid "From Address"
+msgstr ""
+
+#: src/Admin/Pages/ExportTab.php:112
+#: src/Admin/Pages/SmartRoutingTab.php:157
+msgid "Subject"
+msgstr ""
+
+#: src/Admin/Pages/ExportTab.php:113
+msgid "Body"
+msgstr ""
+
+#: src/Admin/Pages/ExportTab.php:114
+msgid "Created Date"
+msgstr ""
+
+#: src/Admin/Pages/ExportTab.php:115
+msgid "Number of Attachments"
+msgstr ""
+
+#: src/Admin/Pages/ExportTab.php:116
+msgid "Attachments"
+msgstr ""
+
+#: src/Admin/Pages/ExportTab.php:120
+msgid "Additional Information"
+msgstr ""
+
+#: src/Admin/Pages/ExportTab.php:121
+msgid "Status"
+msgstr ""
+
+#: src/Admin/Pages/ExportTab.php:122
+msgid "Carbon Copy (CC)"
+msgstr ""
+
+#: src/Admin/Pages/ExportTab.php:123
+msgid "Blind Carbon Copy (BCC)"
+msgstr ""
+
+#: src/Admin/Pages/ExportTab.php:124
+msgid "Headers"
+msgstr ""
+
+#: src/Admin/Pages/ExportTab.php:126
+msgid "Error Details"
+msgstr ""
+
+#: src/Admin/Pages/ExportTab.php:127
+msgid "Email log ID"
+msgstr ""
+
+#: src/Admin/Pages/ExportTab.php:132
+msgid "Custom Date Range"
+msgstr ""
+
+#: src/Admin/Pages/ExportTab.php:137
+msgid "Search"
+msgstr ""
+
+#: src/Admin/Pages/ExportTab.php:139
+msgid "Email Addresses"
+msgstr ""
+
+#: src/Admin/Pages/LogsTab.php:130
+msgid "Email Log Index"
+msgstr ""
+
+#: src/Admin/Pages/LogsTab.php:135
+#: src/Admin/Pages/SettingsTab.php:226
+msgid "Individual Email Log"
+msgstr ""
+
+#: src/Admin/Pages/LogsTab.php:147
+msgid "Email logging makes it easy to save details about all of the emails sent from your WordPress site. You can search and filter the email log to find specific messages and check the color-coded delivery status. Email logging also allows you to resend emails, save attachments, and export your logs in different formats."
+msgstr ""
+
+#: src/Admin/Pages/LogsTab.php:171
+msgid "Unlock these awesome logging features:"
+msgstr ""
+
+#: src/Admin/Pages/LogsTab.php:174
+msgid "Save detailed email headers"
+msgstr ""
+
+#: src/Admin/Pages/LogsTab.php:175
+msgid "See sent and failed emails"
+msgstr ""
+
+#: src/Admin/Pages/LogsTab.php:178
+msgid "Resend emails and attachments"
+msgstr ""
+
+#: src/Admin/Pages/LogsTab.php:179
+msgid "Track email opens and clicks"
+msgstr ""
+
+#: src/Admin/Pages/LogsTab.php:182
+msgid "Print email logs or save as PDF"
+msgstr ""
+
+#: src/Admin/Pages/LogsTab.php:183
+msgid "Export logs to CSV, XLSX, or EML"
+msgstr ""
+
+#: src/Admin/Pages/MiscTab.php:40
+msgid "Misc"
+msgstr ""
+
+#: src/Admin/Pages/MiscTab.php:52
+msgid "Miscellaneous"
+msgstr ""
+
+#: src/Admin/Pages/MiscTab.php:79
+msgid "Do Not Send"
+msgstr ""
+
+#: src/Admin/Pages/MiscTab.php:87
+msgid "Some plugins, like BuddyPress and Events Manager, are using their own email delivery solutions. By default, this option does not block their emails, as those plugins do not use default wp_mail() function to send emails."
+msgstr ""
+
+#: src/Admin/Pages/MiscTab.php:96
+msgid "You will need to consult with their documentation to switch them to use default WordPress email delivery."
+msgstr ""
+
+#: src/Admin/Pages/MiscTab.php:98
+msgid "Test emails are allowed to be sent, regardless of this option."
+msgstr ""
+
+#: src/Admin/Pages/MiscTab.php:115
+msgid "Stop sending all emails"
+msgstr ""
+
+#. translators: %s - The URL to the constants support article.
+#: src/Admin/Pages/MiscTab.php:124
+msgid "Please read this support article if you want to enable this option using constants."
+msgstr ""
+
+#: src/Admin/Pages/MiscTab.php:158
+msgid "Log Blocked Emails"
+msgstr ""
+
+#: src/Admin/Pages/MiscTab.php:161
+msgid "When selected, emails blocked by the \"Do Not Send\" option will be logged in the Email Log."
+msgstr ""
+
+#: src/Admin/Pages/MiscTab.php:174
+msgid "Hide Announcements"
+msgstr ""
+
+#: src/Admin/Pages/MiscTab.php:189
+msgid "Hide plugin announcements and update details."
+msgstr ""
+
+#: src/Admin/Pages/MiscTab.php:199
+msgid "Hide Email Delivery Errors"
+msgstr ""
+
+#: src/Admin/Pages/MiscTab.php:218
+msgid "Hide warnings alerting of email delivery errors."
+msgstr ""
+
+#. translators: %s - filter that was used to disabled.
+#: src/Admin/Pages/MiscTab.php:224
+msgid "Email Delivery Errors were disabled using a %s filter."
+msgstr ""
+
+#: src/Admin/Pages/MiscTab.php:233
+msgid "This is not recommended and should only be done for staging or development sites."
+msgstr ""
+
+#: src/Admin/Pages/MiscTab.php:248
+msgid "Hide Dashboard Widget"
+msgstr ""
+
+#: src/Admin/Pages/MiscTab.php:263
+msgid "Hide the WP Mail SMTP Dashboard Widget."
+msgstr ""
+
+#: src/Admin/Pages/MiscTab.php:273
+msgid "Allow Usage Tracking"
+msgstr ""
+
+#: src/Admin/Pages/MiscTab.php:298
+msgid "Disable Email Summaries"
+msgstr ""
+
+#: src/Admin/Pages/MiscTab.php:317
+msgid "Disable Email Summaries weekly delivery."
+msgstr ""
+
+#. translators: %s - Email Log settings url.
+#: src/Admin/Pages/MiscTab.php:322
+msgid "Please enable Email Logging first, before this setting can be configured."
+msgstr ""
+
+#: src/Admin/Pages/MiscTab.php:335
+msgid "View Email Summary Example"
+msgstr ""
+
+#: src/Admin/Pages/MiscTab.php:351
+msgid "Optimize Email Sending"
+msgstr ""
+
+#. translators: %1$s - Documentation URL.
+#: src/Admin/Pages/MiscTab.php:369
+msgid "Send emails asynchronously, which will make pages with email requests load faster, but may delay email delivery by a minute or two. Learn More"
+msgstr ""
+
+#: src/Admin/Pages/MiscTab.php:400
+msgid "Uninstall WP Mail SMTP"
+msgstr ""
+
+#: src/Admin/Pages/MiscTab.php:415
+msgid "Remove ALL WP Mail SMTP data upon plugin deletion."
+msgstr ""
+
+#: src/Admin/Pages/MiscTab.php:418
+msgid "All settings will be unrecoverable."
+msgstr ""
+
+#: src/Admin/Pages/MiscTab.php:440
+msgid "Email Rate Limiting"
+msgstr ""
+
+#. translators: %1$s - Documentation URL.
+#: src/Admin/Pages/MiscTab.php:455
+msgid "Limit the number of emails this site will send in each time interval (per minute, hour, day, week and month). Emails that will cross those set limits will be queued and sent as soon as your limits allow. Learn More"
+msgstr ""
+
+#: src/Admin/Pages/SettingsTab.php:64
+msgid "License"
+msgstr ""
+
+#: src/Admin/Pages/SettingsTab.php:67
+msgid "Your license key provides access to updates and support."
+msgstr ""
+
+#: src/Admin/Pages/SettingsTab.php:74
+msgid "You're using WP Mail SMTP Lite - no license needed. Enjoy!"
+msgstr ""
+
+#. Translators: %s - discount value $50
+#: src/Admin/Pages/SettingsTab.php:80
+msgid "As a valued WP Mail SMTP Lite user, you can enjoy an exclusive %s discount, automatically applied at checkout to unlock even more features!"
+msgstr ""
+
+#: src/Admin/Pages/SettingsTab.php:98
+msgid "License Key"
+msgstr ""
+
+#: src/Admin/Pages/SettingsTab.php:108
+msgid "Primary Connection"
+msgstr ""
+
+#: src/Admin/Pages/SettingsTab.php:116
+msgid "Setup Wizard"
+msgstr ""
+
+#: src/Admin/Pages/SettingsTab.php:120
+msgid "Launch Setup Wizard"
+msgstr ""
+
+#: src/Admin/Pages/SettingsTab.php:124
+msgid "We'll guide you through each step needed to get WP Mail SMTP fully set up on your site."
+msgstr ""
+
+#: src/Admin/Pages/SettingsTab.php:164
+msgid "Already purchased? Simply enter your license key below to connect with WP Mail SMTP Pro!"
+msgstr ""
+
+#: src/Admin/Pages/SettingsTab.php:168
+msgid "Paste license key here"
+msgstr ""
+
+#: src/Admin/Pages/SettingsTab.php:221
+msgid "Email Logs"
+msgstr ""
+
+#: src/Admin/Pages/SettingsTab.php:245
+msgid "Level Up Your Email Game - Get Pro Features Now"
+msgstr ""
+
+#: src/Admin/Pages/SettingsTab.php:248
+msgid "Upgrade and join over 4,000,000 websites!"
+msgstr ""
+
+#: src/Admin/Pages/SettingsTab.php:254
+msgid "Key Features Youāll Unlock:"
+msgstr ""
+
+#: src/Admin/Pages/SettingsTab.php:259
+msgid "Peace of Mind - Never wonder about your email status"
+msgstr ""
+
+#: src/Admin/Pages/SettingsTab.php:260
+msgid "Email Logging, Alerts, and Backup Connection"
+msgstr ""
+
+#: src/Admin/Pages/SettingsTab.php:263
+msgid "Professional Email Services - Access enterprise-grade email providers"
+msgstr ""
+
+#: src/Admin/Pages/SettingsTab.php:264
+msgid "Gmail one-click setup, Microsoft 365 / Outlook, Amazon SES, and Zoho Mail"
+msgstr ""
+
+#: src/Admin/Pages/SettingsTab.php:267
+msgid "Effortless Management - Control your email experience"
+msgstr ""
+
+#: src/Admin/Pages/SettingsTab.php:268
+msgid "Smart Routing, Multisite Support, and Manage Notifications"
+msgstr ""
+
+#: src/Admin/Pages/SettingsTab.php:271
+msgid "White Glove Setup - Sit back while we handle everything"
+msgstr ""
+
+#: src/Admin/Pages/SettingsTab.php:272
+msgid "Professional Setup and World-Class Support"
+msgstr ""
+
+#: src/Admin/Pages/SettingsTab.php:283
+msgid "Discount"
+msgstr ""
+
+#. Translators: %s - discount value $50.
+#: src/Admin/Pages/SettingsTab.php:288
+msgid "%s OFF for WP Mail SMTP users, applied at checkout."
+msgstr ""
+
+#. translators: %s - WPMailSMTP.com Upgrade page URL.
+#: src/Admin/Pages/SettingsTab.php:343
+msgid "Donāt worry about losing emails. Add an additional connection, then set it as your Backup Connection. Emails that fail to send with the Primary Connection will be sent via the selected Backup Connection. Upgrade to WP Mail SMTP Pro!"
+msgstr ""
+
+#. translators: %s - Smart routing settings page url.
+#: src/Admin/Pages/SettingsTab.php:375
+msgid "Once you add an additional connection, you can select it here."
+msgstr ""
+
+#: src/Admin/Pages/SmartRoutingTab.php:106
+msgid "Send emails from different additional connections based on your configured conditions. Emails that do not match any of the conditions below will be sent via your Primary Connection."
+msgstr ""
+
+#: src/Admin/Pages/SmartRoutingTab.php:119
+msgid "Enable Smart Routing"
+msgstr ""
+
+#: src/Admin/Pages/SmartRoutingTab.php:130
+#: src/Admin/Pages/SmartRoutingTab.php:242
+msgid "Send with"
+msgstr ""
+
+#: src/Admin/Pages/SmartRoutingTab.php:132
+msgid "WooCommerce Emails (SendLayer)"
+msgstr ""
+
+#: src/Admin/Pages/SmartRoutingTab.php:134
+#: src/Admin/Pages/SmartRoutingTab.php:246
+msgid "if the following conditions are met..."
+msgstr ""
+
+#: src/Admin/Pages/SmartRoutingTab.php:138
+#: src/Admin/Pages/SmartRoutingTab.php:250
+msgid "Arrow Up"
+msgstr ""
+
+#: src/Admin/Pages/SmartRoutingTab.php:141
+#: src/Admin/Pages/SmartRoutingTab.php:253
+msgid "Arrow Down"
+msgstr ""
+
+#: src/Admin/Pages/SmartRoutingTab.php:162
+msgid "Contains"
+msgstr ""
+
+#: src/Admin/Pages/SmartRoutingTab.php:166
+msgid "Order"
+msgstr ""
+
+#: src/Admin/Pages/SmartRoutingTab.php:170
+#: src/Admin/Pages/SmartRoutingTab.php:193
+#: src/Admin/Pages/SmartRoutingTab.php:223
+#: src/Admin/Pages/SmartRoutingTab.php:282
+msgid "And"
+msgstr ""
+
+#: src/Admin/Pages/SmartRoutingTab.php:185
+#: src/Admin/Pages/SmartRoutingTab.php:215
+#: src/Admin/Pages/SmartRoutingTab.php:274
+msgid "Is"
+msgstr ""
+
+#: src/Admin/Pages/SmartRoutingTab.php:202
+#: src/Admin/Pages/SmartRoutingTab.php:232
+#: src/Admin/Pages/SmartRoutingTab.php:291
+msgid "or"
+msgstr ""
+
+#: src/Admin/Pages/SmartRoutingTab.php:235
+#: src/Admin/Pages/SmartRoutingTab.php:294
+msgid "Add New Group"
+msgstr ""
+
+#: src/Admin/Pages/SmartRoutingTab.php:244
+msgid "Contact Emails (SMTP.com)"
+msgstr ""
+
+#: src/Admin/Pages/SmartRoutingTab.php:269
+msgid "Initiator"
+msgstr ""
+
+#: src/Admin/Pages/SmartRoutingTab.php:301
+msgid "Light bulb icon"
+msgstr ""
+
+#: src/Admin/Pages/SmartRoutingTab.php:302
+msgid "Friendly reminder, your Primary Connection will be used for all emails that do not match the conditions above."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:113
+msgid "Email Test"
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:164
+msgid "Enter email address where test email will be sent."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:181
+msgid "HTML"
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:194
+msgid "Send this email in HTML or in plain text format."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:214
+msgid "You cannot send an email. Mailer is not properly configured. Please check your settings."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:218
+msgid "Send Email"
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:275
+msgid "Success!"
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:278
+msgid "Test HTML email was sent successfully! Please check your inbox to make sure it was delivered."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:280
+msgid "Test plain text email was sent successfully! Please check your inbox to make sure it was delivered."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:320
+msgid "Test failed. Please use a valid email address and try to resend the test email."
+msgstr ""
+
+#. translators: %s - email address a test email will be sent to.
+#: src/Admin/Pages/TestTab.php:332
+#: src/Admin/Pages/TestTab.php:339
+msgid "Test email to %s"
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:724
+msgid "SSL certificate issue."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:726
+msgid "This means your web server cannot reliably make secure connections (make requests to HTTPS sites)."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:727
+#: src/Admin/Pages/TestTab.php:792
+msgid "Typically this error is returned when web server is not configured properly."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:730
+msgid "Contact your web hosting provider and inform them your site has an issue with SSL certificates."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:731
+#: src/Admin/Pages/TestTab.php:796
+msgid "The exact error you can provide them is in the Error log, available at the bottom of this page."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:732
+#: src/Admin/Pages/TestTab.php:797
+msgid "Ask them to resolve the issue then try again."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:742
+msgid "Could not connect to host."
+msgstr ""
+
+#. translators: %s - SMTP host address.
+#: src/Admin/Pages/TestTab.php:746
+#: src/Admin/Pages/TestTab.php:788
+#: src/Admin/Pages/TestTab.php:904
+msgid "This means your web server was unable to connect to %s."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:749
+#: src/Admin/Pages/TestTab.php:791
+#: src/Admin/Pages/TestTab.php:907
+msgid "This means your web server was unable to connect to the host server."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:750
+msgid "Typically this error is returned your web server is blocking the connections or the SMTP host denying the request."
+msgstr ""
+
+#. translators: %s - SMTP host address.
+#: src/Admin/Pages/TestTab.php:754
+msgid "Contact your web hosting provider and ask them to verify your server can connect to %s. Additionally, ask them if a firewall or security policy may be preventing the connection."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:757
+msgid "If using \"Other SMTP\" Mailer, triple check your SMTP settings including host address, email, and password."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:758
+msgid "If using \"Other SMTP\" Mailer, contact your SMTP host to confirm they are accepting outside connections with the settings you have configured (address, username, port, security, etc)."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:767
+msgid "Invalid SendGrid API key"
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:769
+msgid "It looks like your SendGrid API Key is invalid."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:772
+#: src/Admin/Pages/TestTab.php:859
+msgid "Go to WP Mail SMTP plugin Settings page."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:773
+msgid "Make sure your API Key in the SendGrid mailer settings is correct and valid."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:774
+msgid "Save the plugin settings."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:775
+msgid "If updating the API Key doesn't resolve this issue, please contact our support."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:784
+msgid "Could not connect to your host."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:795
+msgid "Contact your web hosting provider and inform them you are having issues making outbound connections."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:806
+msgid "Could not authenticate your SMTP account."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:808
+msgid "This means we were able to connect to your SMTP host, but were not able to proceed using the email/password in the settings."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:809
+msgid "Typically this error is returned when the email or password is not correct or is not what the SMTP host is expecting."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:812
+msgid "Triple check your SMTP settings including host address, email, and password. If you have recently reset your password you will need to update the settings."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:813
+#: src/Admin/Pages/TestTab.php:940
+msgid "Contact your SMTP host to confirm you are using the correct username and password."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:814
+#: src/Admin/Pages/TestTab.php:941
+msgid "Verify with your SMTP host that your account has permissions to send emails using outside connections."
+msgstr ""
+
+#. translators: %s - URL to the wpmailsmtp.com doc page.
+#: src/Admin/Pages/TestTab.php:817
+msgid "Visit our documentation for additional tips on how to resolve this error."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:837
+msgid "Error due to unsolicited and/or bulk e-mail."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:839
+msgid "This means the connection to your SMTP host was made successfully, but the host rejected the email."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:840
+msgid "Typically this error is returned when you are sending too many e-mails or e-mails that have been identified as spam."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:843
+msgid "Make sure you are not sending emails with too many recipients. Example: single email should not have 10+ recipients. You can install any WordPress e-mail logging plugin to check your recipients (TO, CC and BCC)."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:844
+msgid "Contact your SMTP host to ask about sending/rate limits."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:845
+msgid "Verify with them your SMTP account is in good standing and your account has not been flagged."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:854
+msgid "Unauthenticated senders are not allowed."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:856
+msgid "This means the connection to your SMTP host was made successfully, but you should enable Authentication and provide correct Username and Password."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:861
+msgid "Enter correct SMTP Username (usually this is an email address) and Password in the appropriate fields."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:872
+msgid "Misconfigured server certificate."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:874
+msgid "This means OpenSSL on your server isn't able to verify the host certificate."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:875
+msgid "There are a few reasons why this is happening. It could be that the host certificate is misconfigured, or this server's OpenSSL is using an outdated CA bundle."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:878
+msgid "Verify that the host's SSL certificate is valid."
+msgstr ""
+
+#. translators: %s - URL to the PHP openssl manual
+#: src/Admin/Pages/TestTab.php:881
+msgid "Contact your hosting support, show them the \"full Error Log for debugging\" below and share this link with them."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:900
+msgid "Could not connect to the SMTP host."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:908
+#: src/Admin/Pages/TestTab.php:1372
+msgid "Typically this error is returned for one of the following reasons:"
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:911
+msgid "SMTP settings are incorrect (wrong port, security setting, incorrect host)."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:914
+#: src/Admin/Pages/TestTab.php:1378
+msgid "Your web server is blocking the connection."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:917
+msgid "Your SMTP host is rejecting the connection."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:922
+msgid "Triple check your SMTP settings including host address, email, and password, port, and security."
+msgstr ""
+
+#. translators: %1$s - SMTP host address, %2$s - SMTP port, %3$s - SMTP encryption.
+#: src/Admin/Pages/TestTab.php:925
+msgid "Contact your web hosting provider and ask them to verify your server can connect to %1$s on port %2$s using %3$s encryption. Additionally, ask them if a firewall or security policy may be preventing the connection - many shared hosts block certain ports. Note: this is the most common cause of this issue."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:938
+msgid "no"
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:950
+#: src/Admin/Pages/TestTab.php:965
+#: src/Admin/Pages/TestTab.php:1005
+msgid "Mailgun failed."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:952
+msgid "It seems that you forgot to activate your Mailgun account."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:955
+msgid "Check your inbox you used to create a Mailgun account. Click the activation link in an email from Mailgun."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:956
+msgid "If you do not see activation email, go to your Mailgun control panel and resend the activation email."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:967
+msgid "Typically this error occurs because there is an issue with your Mailgun settings, in many cases Mailgun API Key, Domain Name, or Region is incorrect."
+msgstr ""
+
+#. translators: %1$s - Mailgun API Key area URL.
+#: src/Admin/Pages/TestTab.php:972
+msgid "Go to your Mailgun account and verify that your Mailgun API Key is correct."
+msgstr ""
+
+#. translators: %1$s - Mailgun domains area URL.
+#: src/Admin/Pages/TestTab.php:985
+msgid "Verify your Domain Name is correct."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:996
+msgid "Verify your domain Region is correct."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1007
+msgid "Your Mailgun account does not have access to send emails."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1008
+msgid "Typically this error occurs because you have not set up and/or complete domain name verification for your Mailgun account."
+msgstr ""
+
+#. translators: %s - Mailgun documentation URL.
+#: src/Admin/Pages/TestTab.php:1013
+msgid "Go to our how-to guide for setting up Mailgun with WP Mail SMTP."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1025
+msgid "Complete the steps in section \"2. Verify Your Domain\"."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1034
+#: src/Admin/Pages/TestTab.php:1083
+#: src/Admin/Pages/TestTab.php:1103
+#: src/Admin/Pages/TestTab.php:1131
+#: src/Admin/Pages/TestTab.php:1147
+#: src/Admin/Pages/TestTab.php:1199
+#: src/Admin/Pages/TestTab.php:1225
+msgid "Google API Error."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1036
+msgid "You have not properly configured Gmail mailer."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1037
+msgid "Make sure that you have clicked the \"Allow plugin to send emails using your Google account\" button under Gmail settings."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1040
+msgid "Go to plugin Settings page and click the \"Allow plugin to send emails using your Google account\" button."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1041
+msgid "After the click you should be redirected to a Gmail authorization screen, where you will be asked a permission to send emails on your behalf."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1042
+msgid "Please click \"Agree\", if you see that button. If not - you will need to enable less secure apps first:"
+msgstr ""
+
+#. translators: %s - Google support article URL.
+#: src/Admin/Pages/TestTab.php:1047
+msgid "if you are using regular Gmail account, please read this article to proceed."
+msgstr ""
+
+#. translators: %s - Google support article URL.
+#: src/Admin/Pages/TestTab.php:1062
+msgid "if you are using Google Workspace, please read this article to proceed."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1085
+msgid "Typically this error occurs because the address to which the email was sent to is invalid or was empty."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1088
+msgid "Check the \"Send To\" email address used and confirm it is a valid email and was not empty."
+msgstr ""
+
+#. translators: 1 - correct email address example. 2 - incorrect email address example.
+#: src/Admin/Pages/TestTab.php:1090
+msgid "It should be something like this: %1$s. These are incorrect values: %2$s."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1094
+msgid "Make sure that the generated email has a TO header, useful when you are responsible for email creation."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1105
+msgid "Unfortunately, this error can be due to many different reasons."
+msgstr ""
+
+#. translators: %s - Blog article URL.
+#: src/Admin/Pages/TestTab.php:1108
+msgid "Please read this article to learn more about what can cause this error and follow the steps below."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1121
+#: src/Providers/Gmail/Mailer.php:249
+msgid "Go to WP Mail SMTP plugin settings page. Click the āRemove OAuth Connectionā button."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1122
+#: src/Providers/Gmail/Mailer.php:250
+msgid "Then click the āAllow plugin to send emails using your Google accountā button and re-enable access."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1133
+msgid "Authentication code that Google returned to you has already been used on your previous auth attempt."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1136
+msgid "Make sure that you are not trying to manually clean up the plugin options to retry the \"Allow...\" step."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1137
+msgid "Reinstall the plugin with clean plugin data turned on on Misc page. This will remove all the plugin options and you will be safe to retry."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1138
+msgid "Make sure there is no aggressive caching on site admin area pages or try to clean cache between attempts."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1149
+msgid "There are various reasons for that, please review the steps below."
+msgstr ""
+
+#. translators: %s - Google Workspace Admin area URL.
+#: src/Admin/Pages/TestTab.php:1154
+msgid "Make sure that your Google Workspace trial period has not expired. You can check the status here."
+msgstr ""
+
+#. translators: %s - Google Workspace Admin area URL.
+#: src/Admin/Pages/TestTab.php:1167
+msgid "Make sure that Gmail app in your Google Workspace is actually enabled. You can check that in Apps list in Google Workspace Admin area."
+msgstr ""
+
+#. translators: %s - Google Developers Console URL.
+#: src/Admin/Pages/TestTab.php:1180
+msgid "Make sure that you have Gmail API enabled, and you can do that here."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1202
+#: src/Admin/Pages/TestTab.php:1230
+msgid "Make sure that the used Client ID/Secret correspond to a proper project that has Gmail API enabled."
+msgstr ""
+
+#. translators: %s - Gmail documentation URL.
+#: src/Admin/Pages/TestTab.php:1205
+msgid "Please follow our Gmail tutorial to be sure that all the correct project and data is applied."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1227
+msgid "You may have added a new API to a project"
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1231
+msgid "Try to use a separate project for your emails, so the project has only 1 Gmail API in it enabled. You will need to remove the old project and create a new one from scratch."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1240
+msgid "SMTP.com API Error."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1242
+msgid "Your Sender Name option is incorrect."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1245
+msgid "Please make sure you entered an accurate Sender Name in WP Mail SMTP plugin settings."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1254
+msgid "GuzzleHttp requirements."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1256
+msgid "GuzzleHttp requires cURL, the allow_url_fopen ini setting, or a custom HTTP handler."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1259
+msgid "Edit your php.ini file on your hosting server."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1260
+msgid "(Recommended) Enable PHP extension: cURL, by adding \"extension=curl\" to the php.ini file (without the quotation marks) OR"
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1261
+msgid "(If cURL can't be enabled on your hosting server) Enable PHP setting: allow_url_fopen, by adding \"allow_url_fopen = On\" to the php.ini file (without the quotation marks)"
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1262
+msgid "If you don't know how to do the above we strongly suggest contacting your hosting support and provide them the \"full Error Log for debugging\" below and these steps. They should be able to fix this issue for you."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1271
+#: src/Admin/Pages/TestTab.php:1300
+msgid "SparkPost API failed."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1273
+msgid "Typically this error occurs because there is an issue with your SparkPost settings, in many cases an incorrect API key."
+msgstr ""
+
+#. translators: %1$s - SparkPost API Keys area URL, %1$s - SparkPost EU API Keys area URL.
+#: src/Admin/Pages/TestTab.php:1278
+msgid "Go to your SparkPost account or SparkPost EU account and verify that your API key is correct."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1291
+msgid "Verify that your API key has \"Transmissions: Read/Write\" permission."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1302
+msgid "Typically this error occurs because there is an issue with your SparkPost settings, in many cases an incorrect region."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1305
+msgid "Verify that your SparkPost account region is selected in WP Mail SMTP settings."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1326
+msgid "PCRE library issue"
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1328
+msgid "It looks like your server is running PHP version 7.4.x with an outdated PCRE library (libpcre2) that has a known issue with email address validation."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1329
+msgid "There is a known issue with PHP version 7.4.x, when using libpcre2 library version lower than 10.33."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1332
+msgid "Contact your web hosting provider and inform them you are having issues with libpcre2 library on PHP 7.4."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1333
+msgid "They should be able to resolve this issue for you."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1334
+msgid "For a quick fix, until your web hosting resolves this, you can downgrade to PHP version 7.3 on your server."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1369
+msgid "An issue was detected."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1371
+msgid "This means your test email was unable to be sent."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1375
+msgid "Plugin settings are incorrect (wrong SMTP settings, invalid Mailer configuration, etc)."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1381
+msgid "Your host is rejecting the connection."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1386
+msgid "Triple-check the plugin settings and consider reconfiguring to make sure everything is correct. Maybe there was an issue with copy&pasting."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1388
+msgid "Contact your web hosting provider and ask them to verify your server can make outside connections. Additionally, ask them if a firewall or security policy may be preventing the connection - many shared hosts block certain ports. Note: this is the most common cause of this issue."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1394
+msgid "Try using a different mailer."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1432
+msgid "There was a problem while sending the test email."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1449
+msgid "Recommended next steps:"
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1457
+msgid "Need support?"
+msgstr ""
+
+#. translators: %s - WPMailSMTP.com account area link.
+#: src/Admin/Pages/TestTab.php:1465
+msgid "As a WP Mail SMTP Pro user you have access to WP Mail SMTP priority support. Please log in to your WPMailSMTP.com account and submit a support ticket."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1483
+msgid "WP Mail SMTP is a free plugin, and the team behind WPForms maintains it to give back to the WordPress community."
+msgstr ""
+
+#. translators: %s - WPMailSMTP.com URL.
+#: src/Admin/Pages/TestTab.php:1490
+msgid "To access our world class support, please upgrade to WP Mail SMTP Pro. Along with getting expert support, you will also get Notification controls, Email Logging, and integrations for Amazon SES, Office 365, and Outlook.com."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1505
+msgid "Additionally, you can take advantage of our White Glove Setup. Sit back and relax while we handle everything for you! If you simply don't have time or maybe you feel a bit in over your head - we got you covered."
+msgstr ""
+
+#. Translators: %s - discount value $50
+#: src/Admin/Pages/TestTab.php:1512
+msgid "As a valued WP Mail SMTP user, you will get %s off regular pricing, automatically applied at checkout!"
+msgstr ""
+
+#. translators: %1$s - WP Mail SMTP support policy URL, %2$s - WP Mail SMTP support forum URL, %3$s - WPMailSMTP.com URL.
+#: src/Admin/Pages/TestTab.php:1528
+msgid "Alternatively, we also offer limited support on the WordPress.org support forums. You can create a support thread there, but please understand that free support is not guaranteed and is limited to simple issues. If you have an urgent or complex issue, then please consider upgrading to WP Mail SMTP Pro to access our priority support ticket system."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1547
+msgid "Please copy the error log message below into the support ticket."
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1552
+msgid "View Full Error Log"
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1556
+msgid "Copy Error Log"
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1559
+msgid "Copied"
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1570
+#: src/Admin/Pages/TestTab.php:1601
+msgid "Send Another Test Email"
+msgstr ""
+
+#: src/Admin/Pages/TestTab.php:1593
+msgid "The test email might have sent, but its deliverability should be improved."
+msgstr ""
+
+#: src/Admin/Pages/Tools.php:41
+msgid "Tools"
+msgstr ""
+
+#: src/Admin/Pages/VersusTab.php:41
+msgid "Lite vs Pro"
+msgstr ""
+
+#. translators: %s - plugin current license type.
+#: src/Admin/Pages/VersusTab.php:72
+msgid "%s vs Pro"
+msgstr ""
+
+#: src/Admin/Pages/VersusTab.php:80
+msgid "Get the most out of WP Mail SMTP by upgrading to Pro and unlocking all of the powerful features."
+msgstr ""
+
+#: src/Admin/Pages/VersusTab.php:89
+msgid "Feature"
+msgstr ""
+
+#: src/Admin/Pages/VersusTab.php:99
+msgid "Pro"
+msgstr ""
+
+#: src/Admin/Pages/VersusTab.php:140
+msgid "Get WP Mail SMTP Pro Today and Unlock all of these Powerful Features"
+msgstr ""
+
+#. Translators: %s - discount value $50.
+#: src/Admin/Pages/VersusTab.php:148
+msgid "Bonus: WP Mail SMTP Lite users get %s off regular price, automatically applied at checkout."
+msgstr ""
+
+#: src/Admin/Pages/VersusTab.php:178
+msgid "Mailer Options"
+msgstr ""
+
+#: src/Admin/Pages/VersusTab.php:179
+msgid "WordPress Multisite"
+msgstr ""
+
+#: src/Admin/Pages/VersusTab.php:180
+msgid "Customer Support"
+msgstr ""
+
+#: src/Admin/Pages/VersusTab.php:201
+msgid "Emails are not logged"
+msgstr ""
+
+#: src/Admin/Pages/VersusTab.php:207
+msgid "Access to all Email Logging options right inside WordPress"
+msgstr ""
+
+#: src/Admin/Pages/VersusTab.php:215
+msgid "No controls over whether default WordPress emails are sent"
+msgstr ""
+
+#: src/Admin/Pages/VersusTab.php:221
+msgid "Complete Email Controls management for most default WordPress emails"
+msgstr ""
+
+#: src/Admin/Pages/VersusTab.php:229
+msgid "Limited Mailers"
+msgstr ""
+
+#: src/Admin/Pages/VersusTab.php:229
+msgid "Access is limited to standard mailer options only"
+msgstr ""
+
+#: src/Admin/Pages/VersusTab.php:235
+msgid "Additional Mailer Options"
+msgstr ""
+
+#: src/Admin/Pages/VersusTab.php:235
+msgid "Microsoft Outlook (with Office365 support), Amazon SES and Zoho Mail"
+msgstr ""
+
+#: src/Admin/Pages/VersusTab.php:243
+msgid "No Global Network Settings"
+msgstr ""
+
+#: src/Admin/Pages/VersusTab.php:249
+msgid "All Global Network Settings"
+msgstr ""
+
+#: src/Admin/Pages/VersusTab.php:249
+msgid "Optionally configure settings at the network level or manage separately for each subsite"
+msgstr ""
+
+#: src/Admin/Pages/VersusTab.php:257
+msgid "Limited Support"
+msgstr ""
+
+#: src/Admin/Pages/VersusTab.php:263
+msgid "Priority Support"
+msgstr ""
+
+#: src/Admin/Review.php:137
+msgid "Are you enjoying WP Mail SMTP?"
+msgstr ""
+
+#: src/Admin/Review.php:140
+msgid "No"
+msgstr ""
+
+#: src/Admin/Review.php:144
+msgid "We're sorry to hear you aren't enjoying WP Mail SMTP. We would love a chance to improve. Could you take a minute and let us know what we can do better?"
+msgstr ""
+
+#: src/Admin/Review.php:151
+msgid "Provide Feedback"
+msgstr ""
+
+#: src/Admin/Review.php:156
+msgid "No thanks"
+msgstr ""
+
+#: src/Admin/Review.php:161
+msgid "That's fantastic! Would you consider giving it a 5-star rating on WordPress.org? It will help other users with email issues and it will mean the world to us!"
+msgstr ""
+
+#: src/Admin/Review.php:164
+msgid "Yes, I'll rate it with 5-stars"
+msgstr ""
+
+#: src/Admin/Review.php:166
+msgid "No, maybe later"
+msgstr ""
+
+#: src/Admin/Review.php:167
+msgid "I already did"
+msgstr ""
+
+#: src/Admin/SetupWizard.php:238
+msgid "We're sorry, the %mailer% mailer is not available on your plan. Please upgrade to the PRO plan to unlock all these awesome features."
+msgstr ""
+
+#. Translators: %s - discount value $50
+#: src/Admin/SetupWizard.php:243
+msgid "Bonus: WP Mail SMTP users get %s off regular price, applied at checkout."
+msgstr ""
+
+#: src/Admin/SetupWizard.php:277
+msgid "WP Mail SMTP › Setup Wizard"
+msgstr ""
+
+#: src/Admin/SetupWizard.php:485
+msgid "Whoops, something's not working."
+msgstr ""
+
+#: src/Admin/SetupWizard.php:486
+msgid "It looks like something is preventing JavaScript from loading on your website. WP Mail SMTP requires JavaScript in order to give you the best possible experience."
+msgstr ""
+
+#: src/Admin/SetupWizard.php:488
+msgid "In order to fix this issue, please check each of the items below:"
+msgstr ""
+
+#: src/Admin/SetupWizard.php:491
+msgid "If you are using an ad blocker, please disable it or whitelist the current page."
+msgstr ""
+
+#: src/Admin/SetupWizard.php:492
+msgid "If you aren't already using Chrome, Firefox, Safari, or Edge, then please try switching to one of these popular browsers."
+msgstr ""
+
+#: src/Admin/SetupWizard.php:493
+msgid "Confirm that your browser is updated to the latest version."
+msgstr ""
+
+#: src/Admin/SetupWizard.php:496
+msgid "If you've checked each of these details and are still running into issues, then please get in touch with our support team. Weād be happy to help!"
+msgstr ""
+
+#: src/Admin/SetupWizard.php:502
+msgid "Copy the error message above and paste it in a message to the WP Mail SMTP support team."
+msgstr ""
+
+#: src/Admin/SetupWizard.php:505
+msgid "Contact Us"
+msgstr ""
+
+#: src/Admin/SetupWizard.php:552
+#: src/Admin/SetupWizard.php:570
+#: src/Admin/SetupWizard.php:634
+msgid "You don't have permission to change options for this WP site!"
+msgstr ""
+
+#: src/Admin/SetupWizard.php:858
+msgid "Could not install the plugin. You don't have permission to install plugins."
+msgstr ""
+
+#: src/Admin/SetupWizard.php:862
+msgid "Could not install the plugin. You don't have permission to activate plugins."
+msgstr ""
+
+#: src/Admin/SetupWizard.php:868
+msgid "Could not install the plugin. Plugin slug is missing."
+msgstr ""
+
+#: src/Admin/SetupWizard.php:888
+#: src/Admin/SetupWizard.php:892
+msgid "Could not install the plugin. Don't have file permission."
+msgstr ""
+
+#: src/Admin/SetupWizard.php:906
+msgid "Could not install the plugin. WP Plugin installer initialization failed."
+msgstr ""
+
+#: src/Admin/SetupWizard.php:992
+msgid "Could not install the plugin. WP Plugin installer could not retrieve plugin information."
+msgstr ""
+
+#: src/Admin/SetupWizard.php:1053
+msgid "Contact Forms by WPForms"
+msgstr ""
+
+#: src/Admin/SetupWizard.php:1059
+msgid "All in One SEO"
+msgstr ""
+
+#: src/Admin/SetupWizard.php:1065
+msgid "Google Analytics by MonsterInsights"
+msgstr ""
+
+#: src/Admin/SetupWizard.php:1071
+msgid "Code Snippets by WPCode"
+msgstr ""
+
+#: src/Admin/SetupWizard.php:1077
+msgid "Giveaways by RafflePress"
+msgstr ""
+
+#: src/Admin/SetupWizard.php:1083
+msgid "Smash Balloon Social Photo Feed"
+msgstr ""
+
+#: src/Admin/SetupWizard.php:1089
+msgid "SeedProd Landing Page Builder"
+msgstr ""
+
+#: src/Admin/SetupWizard.php:1095
+msgid "WP Call Button"
+msgstr ""
+
+#: src/Admin/SetupWizard.php:1170
+msgid "You are already using the WP Mail SMTP PRO version. Please refresh this page and verify your license key."
+msgstr ""
+
+#: src/Admin/SetupWizard.php:1174
+msgid "You don't have the permission to perform this action."
+msgstr ""
+
+#: src/Admin/SetupWizard.php:1180
+msgid "Please enter a valid license key!"
+msgstr ""
+
+#: src/Admin/SetupWizard.php:1190
+msgid "Upgrade functionality not available!"
+msgstr ""
+
+#: src/Conflicts.php:310
+msgid "Or disable the Sendinblue email sending setting in WooCommerce > Settings > Sendinblue (tab) > Email Options (tab) > Enable Sendinblue to send WooCommerce emails."
+msgstr ""
+
+#: src/Conflicts.php:342
+msgid "Or enable \"Do not change email sender by default\" setting in Settings > Email template > Sender (tab)."
+msgstr ""
+
+#: src/Conflicts.php:355
+msgid "Or deactivate \"SMTP\" module in Branda > Emails > SMTP."
+msgstr ""
+
+#. translators: %1$s - Plugin name causing conflict.
+#: src/Conflicts.php:520
+msgid "Heads up! WP Mail SMTP has detected %1$s is activated. Please deactivate %1$s to prevent conflicts."
+msgstr ""
+
+#: src/Connect.php:56
+msgid "Almost Done"
+msgstr ""
+
+#: src/Connect.php:57
+msgid "Oops!"
+msgstr ""
+
+#: src/Connect.php:59
+msgid "Unfortunately there was a server connection error."
+msgstr ""
+
+#: src/Connect.php:119
+msgid "You are not allowed to install plugins."
+msgstr ""
+
+#: src/Connect.php:129
+msgid "Please enter your license key to connect."
+msgstr ""
+
+#: src/Connect.php:137
+msgid "Only the Lite version can be upgraded."
+msgstr ""
+
+#: src/Connect.php:152
+msgid "WP Mail SMTP Pro was already installed, but was not active. We activated it for you."
+msgstr ""
+
+#: src/Connect.php:163
+msgid "There was an error while generating an upgrade URL. Please try again."
+msgstr ""
+
+#: src/Connect.php:178
+msgid "There was an error while installing an upgrade. Please download the plugin from wpmailsmtp.com and install it manually."
+msgstr ""
+
+#: src/Connect.php:231
+msgid "There was an error while installing an upgrade. Please check file system permissions and try again. Also, you can download the plugin from wpmailsmtp.com and install it manually."
+msgstr ""
+
+#: src/Connect.php:263
+msgid "There was an error while installing an upgrade. Please try again."
+msgstr ""
+
+#: src/Connect.php:302
+msgid "Pro version installed but needs to be activated on the Plugins page."
+msgstr ""
+
+#: src/Connection.php:52
+msgid "Primary"
+msgstr ""
+
+#. translators: %s - plugin name and its version.
+#: src/Core.php:476
+msgid "EMAILING DISABLED: The %s is currently blocking all emails from being sent."
+msgstr ""
+
+#. translators: %1$s - constant name; %2$s - constant value.
+#: src/Core.php:483
+msgid "To send emails, change the value of the %1$s constant to %2$s."
+msgstr ""
+
+#. translators: %s - plugin Misc settings page URL.
+#: src/Core.php:490
+msgid "To send emails, go to plugin Misc settings and disable the \"Do Not Send\" option."
+msgstr ""
+
+#: src/Core.php:502
+msgid "If you create a test email on this page, it will still be sent."
+msgstr ""
+
+#: src/Core.php:541
+msgid "Heads up! The last email your site attempted to send was unsuccessful."
+msgstr ""
+
+#. translators: %s - plugin admin page URL.
+#: src/Core.php:558
+msgid "Please review your WP Mail SMTP settings in plugin admin area."
+msgstr ""
+
+#. translators: %s - URL to the debug events page.
+#: src/Core.php:571
+msgid "For more details please try running an Email Test or reading the latest error event."
+msgstr ""
+
+#: src/Core.php:1353
+msgid "WP Mail SMTP has detected incorrect \"wp_mail\" function location. Usually, this means that emails will not be sent successfully!"
+msgstr ""
+
+#. translators: %s - plugin name.
+#: src/Core.php:1358
+msgid "It looks like the \"%s\" plugin is overwriting the \"wp_mail\" function. Please reach out to the plugin developer on how to disable or remove the \"wp_mail\" function overwrite to prevent conflicts with WP Mail SMTP."
+msgstr ""
+
+#. translators: %s - must-use plugin name.
+#: src/Core.php:1364
+msgid "It looks like the \"%s\" must-use plugin is overwriting the \"wp_mail\" function. Please reach out to your hosting provider on how to disable or remove the \"wp_mail\" function overwrite to prevent conflicts with WP Mail SMTP."
+msgstr ""
+
+#: src/Core.php:1368
+msgid "It looks like it's overwritten in the \"wp-config.php\" file. Please reach out to your hosting provider on how to disable or remove the \"wp_mail\" function overwrite to prevent conflicts with WP Mail SMTP."
+msgstr ""
+
+#. translators: %s - path.
+#: src/Core.php:1373
+msgid "Current function path: %s"
+msgstr ""
+
+#: src/DBRepair.php:101
+msgid "Unknown."
+msgstr ""
+
+#. translators: %1$s - missing table name; %2$s - error message.
+#: src/DBRepair.php:159
+msgid "Table: %1$s. Reason: %2$s"
+msgstr ""
+
+#: src/DBRepair.php:189
+msgid "Missing DB tables were created successfully."
+msgstr ""
+
+#: src/DBRepair.php:207
+msgid "The following DB table is still missing."
+msgid_plural "The following DB tables are still missing."
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/DBRepair.php:215
+msgid "Some DB Tables are still missing."
+msgstr ""
+
+#: src/Helpers/UI.php:37
+msgid "On"
+msgstr ""
+
+#: src/Helpers/UI.php:38
+msgid "Off"
+msgstr ""
+
+#: src/Helpers/UI.php:87
+msgid "Remove"
+msgstr ""
+
+#: src/MailCatcherTrait.php:228
+#: src/Providers/MailerAbstract.php:308
+msgid "An email request was sent."
+msgstr ""
+
+#: src/MailCatcherTrait.php:246
+msgid "Debug Output:"
+msgstr ""
+
+#: src/MailCatcherTrait.php:316
+msgid "The selected mailer not found."
+msgstr ""
+
+#: src/MailCatcherTrait.php:320
+msgid "The selected mailer is not compatible with your PHP version."
+msgstr ""
+
+#. translators: %1$s - WP Mail SMTP, %2$s - error message.
+#: src/Migration.php:135
+msgid "There was an error while upgrading the database. Please contact %1$s support with this information: %2$s."
+msgstr ""
+
+#. translators: %1$s - the DB option name, %2$s - WP Mail SMTP, %3$s - error message.
+#: src/MigrationAbstract.php:151
+msgid "There was an error while upgrading the %1$s database. Please contact %2$s support with this information: %3$s."
+msgstr ""
+
+#. translators: %1$s - constant that was used; %2$s - file where it was used.
+#: src/Options.php:1743
+msgid "The value of this field was set using a constant %1$s most likely inside %2$s of your WordPress installation."
+msgstr ""
+
+#: src/Pro/SiteHealth.php:60
+msgid "Is wpmailsmtp.com reachable?"
+msgstr ""
+
+#: src/Providers/AmazonSES/Options.php:25
+msgid "Amazon SES"
+msgstr ""
+
+#: src/Providers/AmazonSES/Options.php:39
+msgid "We're sorry, the Amazon SES mailer is not available on your plan. Please upgrade to the PRO plan to unlock all these awesome features."
+msgstr ""
+
+#. translators: %1$s - URL to ElasticEmail.com site.
+#: src/Providers/ElasticEmail/Options.php:37
+msgid "Elastic Email is a cloud-based email marketing platform offering tools for email campaigns, automation, transactional emails, and analytics, designed for businesses of all sizes.
If you're just starting out, you can use Elastic Email's free plan to send emails to your account address from one of your verified email addresses. You don't need to use a credit card to try it out. When you're ready, you can upgrade to a higher plan."
+msgstr ""
+
+#. translators: %2$s - URL to wpmailsmtp.com doc.
+#: src/Providers/ElasticEmail/Options.php:40
+msgid "To get started, read our Elastic Email documentation."
+msgstr ""
+
+#: src/Providers/ElasticEmail/Options.php:59
+msgid "Elastic Email"
+msgstr ""
+
+#: src/Providers/ElasticEmail/Options.php:111
+#: src/Providers/MailerSend/Options.php:106
+#: src/Providers/Mailgun/Options.php:78
+#: src/Providers/Mailjet/Options.php:111
+#: src/Providers/Mandrill/Options.php:107
+#: src/Providers/Resend/Options.php:112
+#: src/Providers/Sendgrid/Options.php:86
+#: src/Providers/Sendinblue/Options.php:130
+#: src/Providers/Sendlayer/Options.php:120
+#: src/Providers/SMTP2GO/Options.php:112
+#: src/Providers/SMTPcom/Options.php:125
+#: src/Providers/SparkPost/Options.php:106
+msgid "Remove API Key"
+msgstr ""
+
+#. translators: %s - link to get an API Key.
+#: src/Providers/ElasticEmail/Options.php:120
+msgid "Follow this link to get an API Key from Elastic Email: %s."
+msgstr ""
+
+#: src/Providers/ElasticEmail/Options.php:122
+#: src/Providers/MailerSend/Options.php:117
+#: src/Providers/Mandrill/Options.php:118
+#: src/Providers/Sendlayer/Options.php:131
+#: src/Providers/SMTPcom/Options.php:135
+#: src/Providers/SparkPost/Options.php:120
+msgid "Get API Key"
+msgstr ""
+
+#: src/Providers/Gmail/Auth.php:151
+msgid "Please make sure your Google Client ID and Secret in the plugin settings are valid. Save the settings and try the Authorization again."
+msgstr ""
+
+#: src/Providers/Gmail/Auth.php:264
+msgid "There was an error while processing the Google authentication request. Please make sure that you have Client ID and Client Secret both valid and saved."
+msgstr ""
+
+#. Translators: %s the error code passed from Google.
+#: src/Providers/Gmail/Auth.php:290
+msgid "There was an error while processing Google authorization: %s"
+msgstr ""
+
+#: src/Providers/Gmail/Auth.php:336
+msgid "There was an error while processing Google authorization: missing code or scope parameter."
+msgstr ""
+
+#. Translators: %s the error message.
+#: src/Providers/Gmail/Auth.php:487
+msgid "An error occurred when trying to get Gmail aliases: %s"
+msgstr ""
+
+#: src/Providers/Gmail/Mailer.php:98
+msgid "An email request was sent to the Gmail API."
+msgstr ""
+
+#: src/Providers/Gmail/Mailer.php:120
+msgid "The response object is invalid (missing getId method)."
+msgstr ""
+
+#: src/Providers/Gmail/Mailer.php:125
+msgid "The email message ID is missing."
+msgstr ""
+
+#: src/Providers/Gmail/Mailer.php:248
+msgid "Please re-grant Google app permissions!"
+msgstr ""
+
+#: src/Providers/Gmail/Options.php:38
+msgid "Google / Gmail"
+msgstr ""
+
+#. translators: %s - URL to our Gmail doc.
+#: src/Providers/Gmail/Options.php:41
+msgid "Our Gmail mailer works with any Gmail or Google Workspace account via the Google API. You can send WordPress emails from your main email address or a Gmail alias, and it's more secure than connecting to Gmail using SMTP credentials. We now have a One-Click Setup, which simply asks you to authorize your Google account to use our app and takes care of everything for you. Alternatively, you can connect manually, which involves several steps that are more technical than other mailer options, so we created a detailed guide to walk you through the process.
To get started, read our Gmail documentation."
+msgstr ""
+
+#: src/Providers/Gmail/Options.php:55
+msgid "The Gmail mailer works well for sites that send low numbers of emails. However, Gmail's API has rate limitations and a number of additional restrictions that can lead to challenges during setup.
If you expect to send a high volume of emails, or if you find that your web host is not compatible with the Gmail API restrictions, then we recommend considering a different mailer option."
+msgstr ""
+
+#: src/Providers/Gmail/Options.php:146
+msgid "Remove Client Secret"
+msgstr ""
+
+#: src/Providers/Gmail/Options.php:158
+msgid "Authorized redirect URI"
+msgstr ""
+
+#: src/Providers/Gmail/Options.php:166
+msgid "Copy URL to clipboard"
+msgstr ""
+
+#: src/Providers/Gmail/Options.php:171
+msgid "Please copy this URL into the \"Authorized redirect URIs\" field of your Google web application."
+msgstr ""
+
+#: src/Providers/Gmail/Options.php:208
+msgid "Allow plugin to send emails using your Google account"
+msgstr ""
+
+#: src/Providers/Gmail/Options.php:211
+msgid "Click the button above to confirm authorization."
+msgstr ""
+
+#. translators: %s - email address, as received from Google API.
+#: src/Providers/Gmail/Options.php:226
+msgid "Connected as %s"
+msgstr ""
+
+#. translators: %s - URL to Google Gmail alias documentation page.
+#: src/Providers/Gmail/Options.php:236
+msgid "If you want to use a different From Email address you can set up a Google email alias. Follow these instructions and then select the From Email at the top of this page."
+msgstr ""
+
+#: src/Providers/Gmail/Options.php:250
+msgid "You can also send emails with different From Email addresses, by disabling the Force From Email setting and using registered aliases throughout your WordPress site as the From Email addresses."
+msgstr ""
+
+#: src/Providers/Gmail/Options.php:253
+msgid "Removing the OAuth connection will give you an ability to redo the OAuth connection or link to another Google account."
+msgstr ""
+
+#: src/Providers/Gmail/Options.php:261
+msgid "You need to save settings with Client ID and Client Secret before you can proceed."
+msgstr ""
+
+#: src/Providers/Mail/Options.php:26
+msgid "Default (none)"
+msgstr ""
+
+#. translators: %1$s - URL to all mailer doc page. %2$s - URL to the setup wizard.
+#: src/Providers/Mail/Options.php:41
+msgid "You currently have the Default (none) mailer selected, which won't improve email deliverability. Please select any other email provider and use the easy Setup Wizard to configure it."
+msgstr ""
+
+#. translators: %1$s - URL to mailersend.com; %2$s - URL to MailerSend documentation on wpmailsmtp.com.
+#: src/Providers/MailerSend/Options.php:41
+msgid "MailerSend is a reliable transactional email provider with powerful features. They offer 12,000 emails per month for free and have affordable plans for higher volumes. Their modern API and excellent deliverability make them a great choice for WordPress sites.
To get started, read our MailerSend documentation."
+msgstr ""
+
+#: src/Providers/MailerSend/Options.php:61
+msgid "MailerSend"
+msgstr ""
+
+#. translators: %s - API key link.
+#: src/Providers/MailerSend/Options.php:115
+msgid "Follow this link to get an API Key from MailerSend: %s."
+msgstr ""
+
+#: src/Providers/MailerSend/Options.php:129
+msgid "Professional Plan"
+msgstr ""
+
+#. translators: %s - MailerSend pricing page URL.
+#: src/Providers/MailerSend/Options.php:148
+msgid "Activate if you have a Professional or higher plan with MailerSend. This allows you to use custom headers. For more information about MailerSend plans, check their %s."
+msgstr ""
+
+#: src/Providers/MailerSend/Options.php:150
+msgid "pricing page"
+msgstr ""
+
+#: src/Providers/Mailgun/Options.php:29
+msgid "Mailgun"
+msgstr ""
+
+#. translators: %1$s - URL to mailgun.com; %2$s - URL to Mailgun documentation on wpmailsmtp.com
+#: src/Providers/Mailgun/Options.php:33
+msgid "Mailgun is a transactional email provider that offers a generous 3-month free trial. After that, it offers a 'Pay As You Grow' plan that allows you to pay for what you use without committing to a fixed monthly rate.
To get started, read our Mailgun documentation."
+msgstr ""
+
+#. translators: %s - API key URL.
+#: src/Providers/Mailgun/Options.php:87
+msgid "Follow this link to get a Mailgun API Key. Generate a key in the \"Mailgun API Keys\" section."
+msgstr ""
+
+#. translators: %s - Domain Name link.
+#: src/Providers/Mailgun/Options.php:118
+msgid "Follow this link to get a Domain Name from Mailgun: %s."
+msgstr ""
+
+#: src/Providers/Mailgun/Options.php:120
+msgid "Get a Domain Name"
+msgstr ""
+
+#: src/Providers/Mailgun/Options.php:154
+msgid "Define which endpoint you want to use for sending messages."
+msgstr ""
+
+#: src/Providers/Mailgun/Options.php:155
+msgid "If you are operating under EU laws, you may be required to use EU region."
+msgstr ""
+
+#. translators: %s - URL to Mailgun.com page.
+#: src/Providers/Mailgun/Options.php:160
+msgid "More information on Mailgun.com."
+msgstr ""
+
+#. translators: %1$s - URL to Mailjet.com site.
+#: src/Providers/Mailjet/Options.php:37
+msgid "Mailjet is a cloud-based email service platform that enables businesses to send marketing and transactional emails, offering features like email automation, real-time analytics, and responsive design templates. If you're just starting out, you can send up to 200 emails per day without a credit card."
+msgstr ""
+
+#. translators: %2$s - URL to wpmailsmtp.com doc.
+#: src/Providers/Mailjet/Options.php:40
+msgid "To get started, read our Mailjet documentation."
+msgstr ""
+
+#: src/Providers/Mailjet/Options.php:59
+msgid "Mailjet"
+msgstr ""
+
+#. translators: %s - link to get an API Key.
+#: src/Providers/Mailjet/Options.php:120
+msgid "Follow this link to get the API key from Mailjet: %s."
+msgstr ""
+
+#: src/Providers/Mailjet/Options.php:122
+#: src/Providers/Mailjet/Options.php:163
+msgid "API Key Management"
+msgstr ""
+
+#: src/Providers/Mailjet/Options.php:152
+msgid "Remove Secret Key"
+msgstr ""
+
+#. translators: %s - link to get an API Key.
+#: src/Providers/Mailjet/Options.php:161
+msgid "Follow this link to get the Secret key from Mailjet: %s."
+msgstr ""
+
+#. translators: %s - The reason the email was rejected.
+#: src/Providers/Mandrill/Mailer.php:416
+msgid "The email failed to be sent. Reason: %s"
+msgstr ""
+
+#: src/Providers/Mandrill/Mailer.php:439
+#: src/Providers/Resend/Mailer.php:426
+#: src/Providers/Sendlayer/Mailer.php:404
+#: src/Providers/SparkPost/Mailer.php:484
+msgid "API Key:"
+msgstr ""
+
+#. translators: %1$s - URL to Mandrill website.
+#: src/Providers/Mandrill/Options.php:38
+msgid "Mandrill is a transactional email API for MailChimp users. It is a reliable, scalable, and secure delivery API for transactional emails. Mandrill requires a paid monthly subscription to send emails."
+msgstr ""
+
+#. translators: %2$s - URL to wpmailsmtp.com doc.
+#: src/Providers/Mandrill/Options.php:41
+msgid "To get started, read our Mandrill documentation."
+msgstr ""
+
+#: src/Providers/Mandrill/Options.php:60
+msgid "Mandrill"
+msgstr ""
+
+#. translators: %s - API key link.
+#: src/Providers/Mandrill/Options.php:116
+msgid "Follow this link to get an API Key from Mandrill: %s."
+msgstr ""
+
+#. translators: %s - constant name: WPMS_SMTP_PASS.
+#: src/Providers/OptionsAbstract.php:374
+msgid "To change the password you need to change the value of the constant there: %s"
+msgstr ""
+
+#. translators: %1$s - wp-config.php file, %2$s - WPMS_ON constant name.
+#: src/Providers/OptionsAbstract.php:382
+msgid "If you want to disable the use of constants, find in %1$s file the constant %2$s and turn if off:"
+msgstr ""
+
+#: src/Providers/OptionsAbstract.php:392
+msgid "All the defined constants will stop working and you will be able to change all the values on this page."
+msgstr ""
+
+#: src/Providers/OptionsAbstract.php:405
+msgid "Remove Password"
+msgstr ""
+
+#: src/Providers/OptionsAbstract.php:411
+msgid "The password is encrypted in the database, but for improved security we recommend using your site's WordPress configuration file to set your password."
+msgstr ""
+
+#: src/Providers/OptionsAbstract.php:417
+msgid "Learn More"
+msgstr ""
+
+#. translators: %1$s - Provider name; %2$s - PHP version required by Provider; %3$s - current PHP version.
+#: src/Providers/OptionsAbstract.php:478
+msgid "%1$s requires PHP %2$s to work and does not support your current PHP version %3$s. Please contact your host and request a PHP upgrade to the latest one."
+msgstr ""
+
+#: src/Providers/OptionsAbstract.php:485
+msgid "Meanwhile you can switch to some other mailers."
+msgstr ""
+
+#. translators: %s - Provider name
+#: src/Providers/OptionsAbstract.php:504
+msgid "%s requires an SSL certificate, and so is not currently compatible with your site. Please contact your host to request a SSL certificate, or check out WPBeginner's tutorial on how to set up SSL."
+msgstr ""
+
+#: src/Providers/OptionsAbstract.php:517
+msgid "If you'd prefer not to set up SSL, or need an SMTP solution in the meantime, please select a different mailer option."
+msgstr ""
+
+#: src/Providers/Outlook/Options.php:25
+msgid "365 / Outlook"
+msgstr ""
+
+#: src/Providers/Outlook/Options.php:39
+msgid "We're sorry, the Microsoft Outlook mailer is not available on your plan. Please upgrade to the PRO plan to unlock all these awesome features."
+msgstr ""
+
+#. translators: %1$s - plugin name; %2$s - documentation link.
+#: src/Providers/Outlook/Provider.php:56
+msgid "%1$s Heads up! Microsoft is discontinuing support for basic SMTP connections. To continue using Outlook or Hotmail, switch to our Outlook mailer for uninterrupted email sending."
+msgstr ""
+
+#. translators: %1$s - Notice message; %2$s - upgrade link.
+#: src/Providers/Outlook/Provider.php:80
+msgid "%1$s Upgrade to Pro now for easy, one-click Outlook setup."
+msgstr ""
+
+#: src/Providers/Pepipost/Options.php:25
+msgid "Pepipost SMTP"
+msgstr ""
+
+#: src/Providers/PepipostAPI/Mailer.php:341
+msgid "General error"
+msgstr ""
+
+#. translators: %1$s - URL to pepipost.com site.
+#: src/Providers/PepipostAPI/Options.php:32
+msgid "Pepipost is a transactional email service. Every month Pepipost delivers over 8 billion emails from 20,000+ customers. Their mission is to reliably send emails in the most efficient way and at the most disruptive pricing ever. Pepipost provides users 30,000 free emails the first 30 days."
+msgstr ""
+
+#. translators: %1$s - URL to wpmailsmtp.com doc.
+#: src/Providers/PepipostAPI/Options.php:35
+msgid "Read our Pepipost documentation to learn how to configure Pepipost and improve your email deliverability."
+msgstr ""
+
+#: src/Providers/PepipostAPI/Options.php:55
+msgid "Get Started with Pepipost"
+msgstr ""
+
+#: src/Providers/PepipostAPI/Options.php:63
+msgid "Pepipost"
+msgstr ""
+
+#. translators: %s - link to get an API Key.
+#: src/Providers/PepipostAPI/Options.php:115
+#: src/Providers/Sendinblue/Options.php:139
+msgid "Follow this link to get an API Key: %s."
+msgstr ""
+
+#: src/Providers/PepipostAPI/Options.php:117
+msgid "Get the API Key"
+msgstr ""
+
+#: src/Providers/Postmark/Mailer.php:414
+msgid "Server API Token:"
+msgstr ""
+
+#: src/Providers/Postmark/Mailer.php:416
+msgid "Message Stream ID:"
+msgstr ""
+
+#. translators: %1$s - URL to postmarkapp.com site.
+#: src/Providers/Postmark/Options.php:34
+msgid "Postmark is a transactional email provider that offers great deliverability and accessible pricing for any business. You can start out with the free trial that allows you to send 100 test emails each month via its secure API."
+msgstr ""
+
+#. translators: %2$s - URL to wpmailsmtp.com doc.
+#: src/Providers/Postmark/Options.php:37
+msgid "To get started, read our Postmark documentation."
+msgstr ""
+
+#: src/Providers/Postmark/Options.php:56
+msgid "Postmark"
+msgstr ""
+
+#: src/Providers/Postmark/Options.php:107
+msgid "Remove Server API Token"
+msgstr ""
+
+#. translators: %s - Server API Token link.
+#: src/Providers/Postmark/Options.php:115
+msgid "Follow this link to get a Server API Token from Postmark: %s."
+msgstr ""
+
+#: src/Providers/Postmark/Options.php:117
+msgid "Get Server API Token"
+msgstr ""
+
+#. translators: %s - URL to Postmark documentation on wpmailsmtp.com
+#: src/Providers/Postmark/Options.php:145
+msgid "Message Stream ID is optional. By default outbound (Default Transactional Stream) will be used. More information can be found in our Postmark documentation."
+msgstr ""
+
+#. translators: %1$s - URL to resend.com site.
+#: src/Providers/Resend/Options.php:38
+msgid "Resend is a modern email delivery platform that enables developers to send transactional and marketing emails quickly and reliably. If you're just getting started, you can send up to 3000 emails per month without a credit card."
+msgstr ""
+
+#. translators: %2$s - URL to wpmailsmtp.com doc.
+#: src/Providers/Resend/Options.php:41
+msgid "To get started, read our Resend documentation."
+msgstr ""
+
+#. translators: %s - link to get an API Key.
+#: src/Providers/Resend/Options.php:121
+msgid "Follow this link to get the API key from Resend: %s."
+msgstr ""
+
+#: src/Providers/Resend/Options.php:123
+msgid "API Keys"
+msgstr ""
+
+#: src/Providers/Sendgrid/Options.php:30
+msgid "SendGrid"
+msgstr ""
+
+#. translators: %1$s - URL to sendgrid.com; %2$s - URL to Sendgrid documentation on wpmailsmtp.com
+#: src/Providers/Sendgrid/Options.php:34
+msgid "SendGrid is a popular transactional email provider that sends more than 35 billion emails every month. If you're just starting out, the free plan allows you to send up to 100 emails each day without entering your credit card details.
To get started, read our SendGrid documentation."
+msgstr ""
+
+#. translators: %s - API key link.
+#: src/Providers/Sendgrid/Options.php:95
+msgid "Follow this link to get an API Key from SendGrid: %s."
+msgstr ""
+
+#: src/Providers/Sendgrid/Options.php:97
+msgid "Create API Key"
+msgstr ""
+
+#. translators: %s - SendGrid access level.
+#: src/Providers/Sendgrid/Options.php:105
+msgid "To send emails you will need only a %s access level for this API key."
+msgstr ""
+
+#. translators: %s - URL to SendGrid documentation on wpmailsmtp.com
+#: src/Providers/Sendgrid/Options.php:129
+msgid "Please input the sending domain/subdomain you configured in your SendGrid dashboard. More information can be found in our SendGrid documentation."
+msgstr ""
+
+#. translators: %1$s - URL to brevo.com site.
+#: src/Providers/Sendinblue/Options.php:39
+msgid "Brevo (formerly Sendinblue) is one of our recommended mailers. It's a transactional email provider with scalable price plans, so it's suitable for any size of business.
If you're just starting out, you can use Brevo's free plan to send up to 300 emails a day. You don't need to use a credit card to try it out. When you're ready, you can upgrade to a higher plan to increase your sending limits."
+msgstr ""
+
+#. translators: %2$s - URL to wpmailsmtp.com doc.
+#: src/Providers/Sendinblue/Options.php:42
+msgid "To get started, read our Brevo documentation."
+msgstr ""
+
+#: src/Providers/Sendinblue/Options.php:63
+msgid "Get Brevo Now (Free)"
+msgstr ""
+
+#: src/Providers/Sendinblue/Options.php:70
+msgid "We believe in full transparency. The Brevo (formerly Sendinblue) links above are tracking links as part of our partnership with Brevo. We can recommend just about any SMTP service, but we only recommend products that we believe will add value to our users."
+msgstr ""
+
+#: src/Providers/Sendinblue/Options.php:77
+msgid "Brevo"
+msgstr ""
+
+#: src/Providers/Sendinblue/Options.php:141
+msgid "Get v3 API Key"
+msgstr ""
+
+#. translators: %s - URL to Sendinblue documentation on wpmailsmtp.com
+#: src/Providers/Sendinblue/Options.php:165
+msgid "Please input the sending domain/subdomain you configured in your Brevo (formerly Sendinblue) dashboard. More information can be found in our Brevo documentation."
+msgstr ""
+
+#. translators: %1$s - URL to sendlayer.com; %2$s - URL to SendLayer documentation on wpmailsmtp.com.
+#: src/Providers/Sendlayer/Options.php:41
+msgid "SendLayer is our #1 recommended mailer. Its affordable pricing and simple setup make it the perfect choice for WordPress sites. SendLayer will authenticate your outgoing emails to make sure they always hit customersā inboxes, and it has detailed documentation to help you authorize your domain.
You can send hundreds of emails for free when you sign up for a trial.
To get started, read our SendLayer documentation."
+msgstr ""
+
+#: src/Providers/Sendlayer/Options.php:73
+msgid "SendLayer"
+msgstr ""
+
+#. translators: %s - API key link.
+#: src/Providers/Sendlayer/Options.php:129
+msgid "Follow this link to get an API Key from SendLayer: %s."
+msgstr ""
+
+#: src/Providers/SMTP/Options.php:28
+msgid "Other SMTP"
+msgstr ""
+
+#. translators: %s - URL to SMTP documentation.
+#: src/Providers/SMTP/Options.php:32
+msgid "The Other SMTP option lets you send emails through an SMTP server instead of using a provider's API. This is easy and convenient, but it's less secure than the other mailers. Please note that your provider may not allow you to send a large number of emails. In that case, please use a different mailer.
To get started, read our Other SMTP documentation."
+msgstr ""
+
+#. translators: %1$s - URL to SMTP2GO.com site.
+#: src/Providers/SMTP2GO/Options.php:38
+msgid "SMTP2GO provides a robust and reliable email delivery service with global infrastructure, real-time analytics, and advanced security features. If you're just starting out, you can use SMTP2GO's free plan to send up to 1000 emails per month."
+msgstr ""
+
+#. translators: %2$s - URL to wpmailsmtp.com doc.
+#: src/Providers/SMTP2GO/Options.php:41
+msgid "To get started, read our SMTP2GO documentation."
+msgstr ""
+
+#: src/Providers/SMTP2GO/Options.php:60
+msgid "SMTP2GO"
+msgstr ""
+
+#. translators: %s - link to get an API Key.
+#: src/Providers/SMTP2GO/Options.php:121
+msgid "Generate an API key on the Sending → API Keys page in your %s."
+msgstr ""
+
+#: src/Providers/SMTP2GO/Options.php:123
+msgid "control panel"
+msgstr ""
+
+#: src/Providers/SMTPcom/Mailer.php:451
+msgid "Api Key:"
+msgstr ""
+
+#: src/Providers/SMTPcom/Mailer.php:453
+msgid "Channel:"
+msgstr ""
+
+#. translators: %s - URL to smtp.com site.
+#: src/Providers/SMTPcom/Options.php:49
+msgid "SMTP.com is one of our recommended mailers. It's a transactional email provider that's currently used by 100,000+ businesses. SMTP.com is an established brand that's been offering email services for more than 20 years.
SMTP.com offers a free 30-day trial that allows you to send up to 50,000 emails."
+msgstr ""
+
+#. translators: %s - URL to wpmailsmtp.com doc page for stmp.com.
+#: src/Providers/SMTPcom/Options.php:57
+msgid "To get started, read our SMTP.com documentation."
+msgstr ""
+
+#: src/Providers/SMTPcom/Options.php:83
+msgid "SMTP.com"
+msgstr ""
+
+#. translators: %s - API key link.
+#: src/Providers/SMTPcom/Options.php:133
+msgid "Follow this link to get an API Key from SMTP.com: %s."
+msgstr ""
+
+#. translators: %s - Channel/Sender Name link for smtp.com documentation.
+#: src/Providers/SMTPcom/Options.php:162
+msgid "Follow this link to get a Sender Name from SMTP.com: %s."
+msgstr ""
+
+#: src/Providers/SMTPcom/Options.php:164
+msgid "Get Sender Name"
+msgstr ""
+
+#: src/Providers/SparkPost/Mailer.php:486
+msgid "Region:"
+msgstr ""
+
+#. translators: %1$s - URL to SparkPost website.
+#: src/Providers/SparkPost/Options.php:34
+msgid "SparkPost is a transactional email provider that's trusted by big brands and small businesses. It sends more than 4 trillion emails each year and reports 99.9%% uptime. You can get started with the free test account that lets you send up to 500 emails per month."
+msgstr ""
+
+#. translators: %2$s - URL to wpmailsmtp.com doc.
+#: src/Providers/SparkPost/Options.php:37
+msgid "To get started, read our SparkPost documentation."
+msgstr ""
+
+#: src/Providers/SparkPost/Options.php:55
+msgid "SparkPost"
+msgstr ""
+
+#. translators: %s - API Key link.
+#: src/Providers/SparkPost/Options.php:118
+msgid "Follow this link to get an API Key from SparkPost: %s."
+msgstr ""
+
+#: src/Providers/SparkPost/Options.php:159
+msgid "Select your SparkPost account region."
+msgstr ""
+
+#. translators: %s - URL to Mailgun.com page.
+#: src/Providers/SparkPost/Options.php:164
+msgid "More information on SparkPost."
+msgstr ""
+
+#: src/Providers/Zoho/Options.php:25
+msgid "Zoho Mail"
+msgstr ""
+
+#: src/Providers/Zoho/Options.php:41
+msgid "We're sorry, the Zoho Mail mailer is not available on your plan. Please upgrade to the PRO plan to unlock all these awesome features."
+msgstr ""
+
+#: src/Queue/Email.php:150
+msgid "Record not found in DB"
+msgstr ""
+
+#: src/Queue/Email.php:162
+msgid "Invalid record format"
+msgstr ""
+
+#. translators: %1$s - JSON error message.
+#: src/Queue/Email.php:171
+msgid "Data JSON decoding error: %1$s"
+msgstr ""
+
+#. translators: %1$s - JSON error message.
+#: src/Queue/Email.php:545
+msgid "Data JSON encoding error: %1$s"
+msgstr ""
+
+#. translators: %1$s - Database error message.
+#: src/Queue/Email.php:600
+msgid "Insert/update SQL query error: %1$s"
+msgstr ""
+
+#. translators: %1$s - exception message.
+#: src/Queue/Queue.php:117
+msgid "[Emails Queue] Skipped enqueueing email. %1$s."
+msgstr ""
+
+#. translators: %1$d - email ID.
+#: src/Queue/Queue.php:143
+msgid "[Emails Queue] Skipped email sending from the queue. Queue::send_email method was called directly. Email ID: %1$d."
+msgstr ""
+
+#. translators: %1$s - exception message; %2$s - email ID.
+#: src/Queue/Queue.php:159
+msgid "[Emails Queue] Skipped email sending from the queue. %1$s. Email ID: %2$s"
+msgstr ""
+
+#. translators: %1$d - email ID; %2$s - email status.
+#: src/Queue/Queue.php:173
+msgid "[Emails Queue] Skipped email sending from the queue. Wrong email status. Email ID: %1$d, email status: %2$s."
+msgstr ""
+
+#. translators: %1$s - exception message; %2$d - email ID.
+#: src/Queue/Queue.php:231
+msgid "[Emails Queue] Failed to update queue record after sending email from the queue. %1$s. Email ID: %2$d"
+msgstr ""
+
+#. translators: %1$s - exception message.
+#: src/Queue/Queue.php:404
+#: src/Queue/Queue.php:698
+msgid "[Emails Queue] Skipped processing enqueued email. %1$s. Email ID: %2$d"
+msgstr ""
+
+#. translators: %s - site domain.
+#: src/Reports/Emails/Summary.php:88
+msgid "Your Weekly WP Mail SMTP Summary for %s"
+msgstr ""
+
+#: src/Reports/Emails/Summary.php:154
+msgid "WP Mail SMTP Weekly Email Summary"
+msgstr ""
+
+#: src/Reports/Emails/Summary.php:169
+#: src/Reports/Emails/Summary.php:173
+msgid "WP Mail SMTP Logo"
+msgstr ""
+
+#. translators: %1$s - link to a site; %2$s - link to the settings page.
+#: src/Reports/Emails/Summary.php:209
+msgid "This email was auto-generated and sent from %1$s. Learn %2$s."
+msgstr ""
+
+#: src/Reports/Emails/Summary.php:211
+msgid "how to disable it"
+msgstr ""
+
+#: src/Reports/Emails/Summary.php:254
+msgid "Hi there,"
+msgstr ""
+
+#: src/Reports/Emails/Summary.php:257
+msgid "Letās see how many emails youāve sent with WP Mail SMTP."
+msgstr ""
+
+#: src/Reports/Emails/Summary.php:265
+msgid "Total Emails"
+msgstr ""
+
+#: src/Reports/Emails/Summary.php:276
+msgid "Last week"
+msgstr ""
+
+#: src/Reports/Emails/Summary.php:292
+msgid "Reports"
+msgstr ""
+
+#: src/Reports/Emails/Summary.php:293
+msgid "Want More Stats?"
+msgstr ""
+
+#: src/Reports/Emails/Summary.php:297
+msgid "Upgrade to WP Mail SMTP Pro and unlock Email Log and advanced Email Reports. Start measuring the success of your emails today!"
+msgstr ""
+
+#: src/SiteHealth.php:97
+msgid "Is WP Mail SMTP mailer setup complete?"
+msgstr ""
+
+#: src/SiteHealth.php:102
+msgid "Do WP Mail SMTP DB tables exist?"
+msgstr ""
+
+#: src/SiteHealth.php:107
+msgid "Is email domain configured properly?"
+msgstr ""
+
+#: src/SiteHealth.php:133
+msgid "Version"
+msgstr ""
+
+#: src/SiteHealth.php:137
+msgid "License key type"
+msgstr ""
+
+#: src/SiteHealth.php:142
+msgid "No debug notices found."
+msgstr ""
+
+#: src/SiteHealth.php:145
+msgid "DB tables"
+msgstr ""
+
+#: src/SiteHealth.php:147
+msgid "No DB tables found."
+msgstr ""
+
+#: src/SiteHealth.php:159
+msgid "Lite install date"
+msgstr ""
+
+#: src/SiteHealth.php:176
+msgid "None selected"
+msgstr ""
+
+#: src/SiteHealth.php:198
+msgid "Current mailer"
+msgstr ""
+
+#: src/SiteHealth.php:203
+msgid "WP Mail SMTP mailer setup is complete"
+msgstr ""
+
+#: src/SiteHealth.php:212
+msgid "The WP Mail SMTP plugin mailer setup is complete. You can send a test email, to make sure it's working properly."
+msgstr ""
+
+#: src/SiteHealth.php:217
+msgid "Test email sending"
+msgstr ""
+
+#: src/SiteHealth.php:225
+msgid "You currently have the default mailer selected, which means that you havenāt set up SMTP yet."
+msgstr ""
+
+#: src/SiteHealth.php:230
+msgid "WP Mail SMTP mailer setup is incomplete"
+msgstr ""
+
+#: src/SiteHealth.php:236
+msgid "The WP Mail SMTP plugin mailer setup is incomplete. Please click on the link below to access plugin settings and configure the mailer."
+msgstr ""
+
+#: src/SiteHealth.php:241
+#: src/SiteHealth.php:375
+msgid "Configure mailer"
+msgstr ""
+
+#: src/SiteHealth.php:258
+msgid "WP Mail SMTP DB tables are created"
+msgstr ""
+
+#: src/SiteHealth.php:264
+msgid "WP Mail SMTP is using custom database tables for some of its features. In order to work properly, the custom tables should be created, and it looks like they exist in your database."
+msgstr ""
+
+#: src/SiteHealth.php:282
+msgid "WP Mail SMTP DB tables check has failed"
+msgstr ""
+
+#. translators: %s - the list of missing tables separated by comma.
+#: src/SiteHealth.php:288
+msgid "Missing table: %s"
+msgid_plural "Missing tables: %s"
+msgstr[0] ""
+msgstr[1] ""
+
+#. translators: %1$s - Settings Page URL; %2$s - The aria label; %3$s - The text that will appear on the link.
+#: src/SiteHealth.php:293
+msgid "WP Mail SMTP is using custom database tables for some of its features. In order to work properly, the custom tables should be created, and it seems they are missing. Please try to %3$s. If this issue persists, please contact our support."
+msgstr ""
+
+#: src/SiteHealth.php:295
+msgid "Go to WP Mail SMTP settings page."
+msgstr ""
+
+#: src/SiteHealth.php:296
+msgid "create the missing DB tables by clicking on this link"
+msgstr ""
+
+#: src/SiteHealth.php:333
+msgid "Current from email domain"
+msgstr ""
+
+#: src/SiteHealth.php:338
+msgid "Email domain is configured correctly"
+msgstr ""
+
+#: src/SiteHealth.php:347
+msgid "All checks for your email domain were successful. It looks like everything is configured correctly."
+msgstr ""
+
+#: src/SiteHealth.php:365
+msgid "Email domain issues detected"
+msgstr ""
+
+#. translators: %s: Directory path.
+#: src/Uploads.php:58
+msgid "Unable to create directory %s. Is its parent directory writable by the server?"
+msgstr ""
+
+#. translators: %s: Directory path.
+#: src/Uploads.php:69
+msgid "Unable to write in WPMailSMTP upload directory %s. Is it writable by the server?"
+msgstr ""
+
+#. translators: %1$s - date, \a\t - specially escaped "at", %2$s - time.
+#: src/WP.php:238
+msgid "%1$s \\a\\t %2$s"
+msgstr ""
+
+#. translators: %s - plugin name.
+#: src/WP.php:585
+msgid "WP Core (%s)"
+msgstr ""
+
+#: src/WP.php:726
+msgid "WP Core"
+msgstr ""
+
+#: wp_mail_smtp.php:169
+msgid "Please deactivate the free version of the WP Mail SMTP plugin before activating WP Mail SMTP Pro."
+msgstr ""
+
+#. translators: %1$s - WPBeginner URL for recommended WordPress hosting.
+#: wp_mail_smtp.php:197
+msgid "Your site is running an insecure version of PHP that is no longer supported. Please contact your web hosting provider to update your PHP version or switch to a recommended WordPress hosting company."
+msgstr ""
+
+#. translators: %s - WPMailSMTP.com docs URL with more details.
+#: wp_mail_smtp.php:225
+msgid "WP Mail SMTP plugin is disabled on your site until you fix the issue. Read more for additional information."
+msgstr ""
+
+#. translators: %s The minimal WP version supported by WP Mail SMTP.
+#: wp_mail_smtp.php:297
+msgid "Your site is running an old version of WordPress that is no longer supported by WP Mail SMTP. Please update your WordPress site to at least version %s."
+msgstr ""
+
+#: wp_mail_smtp.php:308
+msgid "WP Mail SMTP plugin is disabled on your site until WordPress is updated to the required version."
+msgstr ""
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/css/wizard.min.css b/wp-content/plugins/wp-mail-smtp/assets/vue/css/wizard.min.css
new file mode 100755
index 00000000..f2dbb677
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/css/wizard.min.css
@@ -0,0 +1 @@
+.wp-mail-smtp-tooltip{display:block!important;z-index:10000;max-width:350px}.wp-mail-smtp-tooltip .wp-mail-smtp-tooltip-inner{background:#2d4f60;color:#fff;border-radius:5px;padding:16px 20px;font-size:14px}.wp-mail-smtp-tooltip .wp-mail-smtp-tooltip-inner a{color:#fff;font-weight:700}.wp-mail-smtp-tooltip .wp-mail-smtp-tooltip-arrow{width:0;height:0;border-style:solid;position:absolute;margin:5px;border-color:#2d4f60;z-index:1}.wp-mail-smtp-tooltip[x-placement^=top]{padding-bottom:5px}.wp-mail-smtp-tooltip[x-placement^=top] .wp-mail-smtp-tooltip-arrow{border-width:5px 5px 0;border-left-color:rgba(0,0,0,0)!important;border-right-color:rgba(0,0,0,0)!important;border-bottom-color:rgba(0,0,0,0)!important;bottom:0;left:calc(50% - 5px);margin-top:0;margin-bottom:0}.wp-mail-smtp-tooltip[x-placement^=bottom]{padding-top:5px}.wp-mail-smtp-tooltip[x-placement^=bottom] .wp-mail-smtp-tooltip-arrow{border-width:0 5px 5px;border-left-color:rgba(0,0,0,0)!important;border-right-color:rgba(0,0,0,0)!important;border-top-color:rgba(0,0,0,0)!important;top:0;left:calc(50% - 5px);margin-top:0;margin-bottom:0}.wp-mail-smtp-tooltip[x-placement^=right]{padding-left:5px}.wp-mail-smtp-tooltip[x-placement^=right] .wp-mail-smtp-tooltip-arrow{border-width:5px 5px 5px 0;border-left-color:rgba(0,0,0,0)!important;border-top-color:rgba(0,0,0,0)!important;border-bottom-color:rgba(0,0,0,0)!important;left:0;top:calc(50% - 5px);margin-left:0;margin-right:0}.wp-mail-smtp-tooltip[x-placement^=left]{padding-right:5px}.wp-mail-smtp-tooltip[x-placement^=left] .wp-mail-smtp-tooltip-arrow{border-width:5px 0 5px 5px;border-top-color:rgba(0,0,0,0)!important;border-right-color:rgba(0,0,0,0)!important;border-bottom-color:rgba(0,0,0,0)!important;right:0;top:calc(50% - 5px);margin-left:0;margin-right:0}.wp-mail-smtp-tooltip.popover .popover-inner{background:#fff;color:#2d4f60;padding:24px;border-radius:5px;-webkit-box-shadow:0 5px 30px rgba(0,0,0,.1);box-shadow:0 5px 30px rgba(0,0,0,.1)}.wp-mail-smtp-tooltip.popover .popover-arrow{border-color:#fff}.wp-mail-smtp-tooltip[aria-hidden=true]{visibility:hidden;opacity:0;-webkit-transition:opacity .15s,visibility .15s;transition:opacity .15s,visibility .15s}.wp-mail-smtp-tooltip[aria-hidden=false]{visibility:visible;opacity:1;-webkit-transition:opacity .15s;transition:opacity .15s}.wp-mail-smtp-loader{-webkit-animation:wp-mail-smtp-loader-spin .65s linear infinite;animation:wp-mail-smtp-loader-spin .65s linear infinite}.wp-mail-smtp-loader-md{width:32px;height:32px}.wp-mail-smtp-loader-sm{width:16px;height:16px}@-webkit-keyframes wp-mail-smtp-loader-spin{0%{-webkit-transform:rotate(270deg);transform:rotate(270deg)}to{-webkit-transform:rotate(630deg);transform:rotate(630deg)}}@keyframes wp-mail-smtp-loader-spin{0%{-webkit-transform:rotate(270deg);transform:rotate(270deg)}to{-webkit-transform:rotate(630deg);transform:rotate(630deg)}}*{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}body{background:#f1f1f1;margin:0}body,body button,body input,body select,body textarea{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif}p>label{display:block}.medium-bold{font-weight:500}.medium-bold a{color:#e27730;font-weight:700}.medium-bold a:focus,.medium-bold a:hover{color:#c45e1b}.wp-mail-smtp-setup-wizard-header{text-align:center;border-top:4px solid #e27730}.wp-mail-smtp-setup-wizard-header h1{margin:0}.wp-mail-smtp-logo{display:inline-block;width:320px;margin-top:50px;padding:0 10px}.wp-mail-smtp-logo img{width:100%;height:100%}.wp-mail-smtp-setup-wizard-container{max-width:90%;width:auto;margin:0 auto}.wp-mail-smtp-setup-wizard-content{background:#fff;border:1px solid #ddd;border-radius:6px;-webkit-box-shadow:0 2px 5px rgba(0,0,0,.05);box-shadow:0 2px 5px rgba(0,0,0,.05);color:#777;font-size:16px;margin:22px 0 30px}.wp-mail-smtp-setup-wizard-content-container{padding:10px 20px}.wp-mail-smtp-setup-wizard-content .wp-mail-smtp-content-header{margin-bottom:27px}.wp-mail-smtp-setup-wizard-content h2,.wp-mail-smtp-setup-wizard-content h3{color:#222;font-size:24px;font-weight:500;margin:0 0 12px}.wp-mail-smtp-setup-wizard-content h3{font-size:16px;margin:0 0 20px}.wp-mail-smtp-setup-wizard-content .subtitle{font-size:16px;line-height:1.5;margin:0}.wp-mail-smtp-setup-wizard-content .wp-mail-smtp-separator{width:100%;border-top:1px solid #e6e6e6;clear:both;margin:20px 0}.wp-mail-smtp-setup-wizard-content .wp-mail-smtp-separator-no-margin{margin:0}.wp-mail-smtp-setup-wizard-content .wp-mail-smtp-separator-big-margin{margin:30px 0}.wp-mail-smtp-welcome .wp-mail-smtp-setup-wizard-content{text-align:center}.wp-mail-smtp-button{border-radius:3px;border:none;background-color:#f1f1f1;color:#555;cursor:pointer;display:inline-block;font-size:16px;font-weight:400;line-height:19px;padding:15px 30px;text-decoration:none}.wp-mail-smtp-button:focus,.wp-mail-smtp-button:hover{background-color:#d8d8d8}.wp-mail-smtp-button:focus{outline:none}.wp-mail-smtp-button.wp-mail-smtp-button-secondary{background-color:#2d4f60;color:#fff;font-weight:500}.wp-mail-smtp-button.wp-mail-smtp-button-secondary:focus,.wp-mail-smtp-button.wp-mail-smtp-button-secondary:hover{background-color:#1d323d}.wp-mail-smtp-button.wp-mail-smtp-button-secondary:disabled{opacity:.65;cursor:not-allowed;background-color:#2d4f60}.wp-mail-smtp-button.wp-mail-smtp-button-red{background-color:#dc3232;color:#fff;font-weight:500}.wp-mail-smtp-button.wp-mail-smtp-button-red:focus,.wp-mail-smtp-button.wp-mail-smtp-button-red:hover{background-color:#bb2020}.wp-mail-smtp-button.wp-mail-smtp-button-red:disabled{opacity:.65;cursor:not-allowed;background-color:#dc3232}.wp-mail-smtp-button.wp-mail-smtp-button-success{background-color:#6aa08b;color:#fff;font-weight:500}.wp-mail-smtp-button.wp-mail-smtp-button-success:focus,.wp-mail-smtp-button.wp-mail-smtp-button-success:hover{background-color:#548371}.wp-mail-smtp-button.wp-mail-smtp-button-success:disabled{opacity:.65;cursor:not-allowed;background-color:#6aa08b}.wp-mail-smtp-button.wp-mail-smtp-button-main{background-color:#e27730;color:#fff;font-weight:500}.wp-mail-smtp-button.wp-mail-smtp-button-main:focus,.wp-mail-smtp-button.wp-mail-smtp-button-main:hover{background-color:#c45e1b}.wp-mail-smtp-button.wp-mail-smtp-button-main:disabled{opacity:.65;cursor:not-allowed;background-color:#e27730}.wp-mail-smtp-button.wp-mail-smtp-button-small{line-height:23px;font-size:14px;padding:8px 20px}.wp-mail-smtp-button.wp-mail-smtp-button-small .wp-mail-smtp-loader-sm{margin-top:3px;margin-bottom:-3px}.wp-mail-smtp-button.wp-mail-smtp-button-large{line-height:22px;font-size:18px;padding:19px 39px}.wp-mail-smtp-button.wp-mail-smtp-button-disabled,.wp-mail-smtp-button.wp-mail-smtp-button-disabled:focus,.wp-mail-smtp-button.wp-mail-smtp-button-disabled:hover{background-color:#f3f6ff;border-color:#b7c9d9;color:#8aa4b8;font-weight:500;cursor:auto;outline:none}.wp-mail-smtp-button.wp-mail-smtp-button-activated,.wp-mail-smtp-button.wp-mail-smtp-button-activated:focus,.wp-mail-smtp-button.wp-mail-smtp-button-activated:hover{background-color:#fff;border-color:#8aa4b8;color:#8aa4b8;font-weight:500;cursor:auto;outline:none}.wp-mail-smtp-button .text-with-arrow{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.wp-mail-smtp-button .text-with-arrow-right .icon{margin-left:10px}.wp-mail-smtp-button .text-with-arrow-left .icon{margin-right:10px}.wp-mail-smtp-step-below-content{text-align:center;font-size:14px;color:#555;margin:-19px 0 47px}.wp-mail-smtp-setup-wizard-step-footer{display:block;text-align:center;min-height:110px;padding:0 20px;margin-top:30px}.wp-mail-smtp-setup-wizard-step-footer a{font-size:14px;display:block;color:#888;margin:20px 0}.wp-mail-smtp-setup-wizard-step-footer a:active,.wp-mail-smtp-setup-wizard-step-footer a:hover{color:#555;text-decoration:underline}.wp-mail-smtp-setup-wizard-step-footer-buttons{margin-bottom:20px}.wp-mail-smtp-setup-wizard-step-footer-buttons button{width:100%;margin-bottom:10px}.wp-mail-smtp-setup-wizard-step-footer-buttons button:last-child{margin-right:0;margin-bottom:0}.wp-mail-smtp-exit-link{text-align:center;margin-bottom:50px}.wp-mail-smtp-exit-link a{font-size:14px;color:#888;text-decoration:underline}.wp-mail-smtp-exit-link a:active,.wp-mail-smtp-exit-link a:hover{color:#555;text-decoration:underline}.wp-mail-smtp-setup-wizard-timeline{-webkit-box-align:center;-ms-flex-align:center;align-items:center;display:-webkit-box;display:-ms-flexbox;display:flex;margin:41px auto 0;max-width:650px;padding:0 20px}.wp-mail-smtp-setup-wizard-timeline .wp-mail-smtp-setup-wizard-timeline-step-line{background:#ddd;height:2px;margin:0 6px;width:100%}.wp-mail-smtp-setup-wizard-timeline .wp-mail-smtp-setup-wizard-timeline-step-line.wp-mail-smtp-setup-wizard-timeline-line-active{background:#6aa08b}.wp-mail-smtp-setup-wizard-timeline .wp-mail-smtp-setup-wizard-timeline-step{border:none;background-color:#999;border-radius:50%;-ms-flex-negative:0;flex-shrink:0;height:16px;width:16px}.wp-mail-smtp-setup-wizard-timeline .wp-mail-smtp-setup-wizard-timeline-step .icon{display:none}.wp-mail-smtp-setup-wizard-timeline .wp-mail-smtp-setup-wizard-timeline-step.wp-mail-smtp-setup-wizard-timeline-step-active,.wp-mail-smtp-setup-wizard-timeline .wp-mail-smtp-setup-wizard-timeline-step.wp-mail-smtp-setup-wizard-timeline-step-completed{background-color:#6aa08b;position:relative}.wp-mail-smtp-setup-wizard-timeline .wp-mail-smtp-setup-wizard-timeline-step.wp-mail-smtp-setup-wizard-timeline-step-failed{background-color:#d83638;position:relative}.wp-mail-smtp-setup-wizard-timeline .wp-mail-smtp-setup-wizard-timeline-step.wp-mail-smtp-setup-wizard-timeline-step-completed .icon-success,.wp-mail-smtp-setup-wizard-timeline .wp-mail-smtp-setup-wizard-timeline-step.wp-mail-smtp-setup-wizard-timeline-step-failed .icon-failed{color:#fff;display:block;position:absolute;left:3px;top:3px}.wp-mail-smtp-setup-wizard-timeline .wp-mail-smtp-setup-wizard-timeline-step.wp-mail-smtp-setup-wizard-timeline-step-failed .icon-failed{left:4px;top:2px}.wp-mail-smtp-input-radios-with-icons{display:block}.wp-mail-smtp-input-radios-with-icons input{opacity:0;position:absolute}.wp-mail-smtp-input-radios-with-icons label{width:100%;height:52px;color:#222;border:1px solid #ddd;background:#fff;border-radius:3px;font-size:16px;display:block;margin-bottom:20px;padding:9px;cursor:pointer}.wp-mail-smtp-input-radios-with-icons label>*{vertical-align:middle}.wp-mail-smtp-input-radios-with-icons label:hover{border:1px solid #888;-webkit-box-shadow:0 0 0 1px #888;box-shadow:0 0 0 1px #888}.wp-mail-smtp-setup-wizard-step-choose-mailer .wp-mail-smtp-setup-wizard-form-row-highlight .wp-mail-smtp-input-radios-with-icons label{border-color:#2d4f60}.wp-mail-smtp-setup-wizard-step-choose-mailer .wp-mail-smtp-setup-wizard-form-row-highlight .wp-mail-smtp-input-radios-with-icons label:hover{-webkit-box-shadow:0 0 0 1px #2d4f60;box-shadow:0 0 0 1px #2d4f60}.wp-mail-smtp-setup-wizard-step-choose-mailer .wp-mail-smtp-setup-wizard-form-row-highlight .wp-mail-smtp-input-radios-with-icons label.wp-mail-smtp-styled-radio-label-readonly:hover{-webkit-box-shadow:none;box-shadow:none}.wp-mail-smtp-input-radios-with-icons label.wp-mail-smtp-styled-radio-label-checked{border:1px solid #2d4f60;-webkit-box-shadow:0 3px 5px rgba(0,0,0,.1),0 0 0 1px #2d4f60;box-shadow:0 3px 5px rgba(0,0,0,.1),0 0 0 1px #2d4f60}.wp-mail-smtp-input-radios-with-icons label.wp-mail-smtp-styled-radio-label-readonly{color:#999;border:1px solid #ddd;-webkit-box-shadow:none;box-shadow:none;cursor:not-allowed}.wp-mail-smtp-input-radios-with-icons label.wp-mail-smtp-styled-radio-label-readonly img,.wp-mail-smtp-input-radios-with-icons label.wp-mail-smtp-styled-radio-label-readonly svg:not(.icon){opacity:.4}.wp-mail-smtp-input-radios-with-icons img{margin-left:20px}.wp-mail-smtp-input-radios-with-icons .wp-mail-smtp-styled-radio{width:32px;height:32px;position:relative;display:inline-block;border-radius:50%;background-color:#e6e6e6}.wp-mail-smtp-input-radios-with-icons .wp-mail-smtp-styled-radio .icon{display:none}.wp-mail-smtp-input-radios-with-icons .wp-mail-smtp-styled-radio.wp-mail-smtp-styled-radio-checked{background-color:#2d4f60;color:#fff}.wp-mail-smtp-input-radios-with-icons .wp-mail-smtp-styled-radio.wp-mail-smtp-styled-radio-checked .icon{display:block;position:absolute;left:8px;top:8px}.wp-mail-smtp-input-radios-with-icons .wp-mail-smtp-styled-radio-text{margin-left:10px}.wp-mail-smtp-input-radios-with-icons input:focus-visible+.wp-mail-smtp-styled-radio:not(.wp-mail-smtp-styled-radio-checked){-webkit-box-shadow:0 0 0 1px #fff,0 0 0 3px #e6e6e6;box-shadow:0 0 0 1px #fff,0 0 0 3px #e6e6e6}.wp-mail-smtp-setup-wizard-form-row-highlight{background-color:#f8f8f8;padding:20px;margin:0 -20px 20px}.wp-mail-smtp-setup-wizard-form-row-highlight .wp-mail-smtp-input-radios-with-icons label:last-child{margin-bottom:0}.wp-mail-smtp-swal.swal2-container.swal2-shown{background-color:rgba(68,68,68,.5)}.wp-mail-smtp-swal .swal2-popup{padding:10px;border-radius:0;font-size:16px;color:#555;-webkit-box-shadow:0 2px 15px rgba(0,0,0,.15);box-shadow:0 2px 15px rgba(0,0,0,.15)}.wp-mail-smtp-swal .swal2-popup .swal2-header{-webkit-box-align:normal;-ms-flex-align:normal;align-items:normal;margin:40px 40px 12px;padding:0}.wp-mail-smtp-swal .swal2-popup .swal2-header .swal2-title{font-size:24px;color:#222;margin:0;padding:0;font-weight:500;text-align:left}.wp-mail-smtp-swal .swal2-popup .swal2-header .swal2-close{color:#999;font-size:0;width:16px;height:16px;margin:10px 8px 0 0;outline:none}.wp-mail-smtp-swal .swal2-popup .swal2-header .swal2-close:before{content:"";display:inline-block;background:no-repeat url(../img/times-solid-grey.svg);width:18px;height:18px}.wp-mail-smtp-swal .swal2-popup .swal2-content{color:#555;font-size:16px;line-height:23px;padding:0 40px;margin-bottom:37px}.wp-mail-smtp-swal .swal2-popup .swal2-content #swal2-content{text-align:left;font-weight:400}.wp-mail-smtp-swal .swal2-popup .swal2-actions{border-top:1px solid #e6e6e6;margin:0 -10px;padding:30px 30px 20px;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;width:auto}@media(min-width:782px){.wp-mail-smtp-swal .swal2-popup .swal2-actions{-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}}.wp-mail-smtp-swal .swal2-popup .swal2-actions .swal2-styled:focus{-webkit-box-shadow:none;box-shadow:none}.wp-mail-smtp-swal .swal2-popup .swal2-actions .swal2-styled.swal2-cancel,.wp-mail-smtp-swal .swal2-popup .swal2-actions .swal2-styled.swal2-confirm{margin:0;display:block;width:100%}@media(min-width:782px){.wp-mail-smtp-swal .swal2-popup .swal2-actions .swal2-styled.swal2-cancel,.wp-mail-smtp-swal .swal2-popup .swal2-actions .swal2-styled.swal2-confirm{display:inline-block;width:auto}}.wp-mail-smtp-swal .swal2-popup .swal2-actions .swal2-styled.swal2-confirm{border:none;background-color:#e27730;color:#fff;border-radius:3px;font-size:16px;font-weight:500;line-height:19px;padding:15px 30px;text-decoration:none}.wp-mail-smtp-swal .swal2-popup .swal2-actions .swal2-styled.swal2-confirm:focus,.wp-mail-smtp-swal .swal2-popup .swal2-actions .swal2-styled.swal2-confirm:hover{background-color:#c45e1b}.wp-mail-smtp-swal .swal2-popup .swal2-actions .swal2-styled.swal2-confirm:after{content:"";display:inline-block;margin:0 0 -3px 10px;background:no-repeat url(../img/long-arrow-alt-right-regular-white.svg);width:16px;height:18px}.wp-mail-smtp-swal .swal2-popup .swal2-actions .swal2-styled.swal2-cancel{background:none!important;border:none;padding:0!important;color:#888;font-size:14px;font-weight:400;text-decoration:underline;cursor:pointer;margin-bottom:30px}@media(min-width:782px){.wp-mail-smtp-swal .swal2-popup .swal2-actions .swal2-styled.swal2-cancel{margin-bottom:0}}.wp-mail-smtp-swal .swal2-popup .swal2-actions .swal2-styled.swal2-cancel:focus,.wp-mail-smtp-swal .swal2-popup .swal2-actions .swal2-styled.swal2-cancel:hover{color:#555}.wp-mail-smtp-swal .swal2-popup .swal2-actions .swal2-styled.swal2-cancel:before{content:"";margin:0 10px -3px 0;display:inline-block;background:no-repeat url(../img/long-arrow-alt-left-regular-grey.svg);width:16px;height:18px}.wp-mail-smtp-swal.wp-mail-smtp-upgrade-popup .swal2-popup{border-top:7px solid #3498db;padding-top:0}.wp-mail-smtp-swal.wp-mail-smtp-upgrade-popup .swal2-popup .swal2-header{margin:10px 40px 24px;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.wp-mail-smtp-swal.wp-mail-smtp-upgrade-popup .swal2-popup .swal2-header .swal2-image{margin-top:30px;margin-bottom:17px}.wp-mail-smtp-swal.wp-mail-smtp-upgrade-popup .swal2-popup .swal2-header .swal2-title{font-weight:700;text-align:center}.wp-mail-smtp-swal.wp-mail-smtp-upgrade-popup .swal2-popup .swal2-content{margin-bottom:0}.wp-mail-smtp-swal.wp-mail-smtp-upgrade-popup .swal2-popup .swal2-content p{margin:0 auto 25px}.wp-mail-smtp-swal.wp-mail-smtp-upgrade-popup .swal2-popup .swal2-content p:last-child{margin-bottom:0}.wp-mail-smtp-swal.wp-mail-smtp-upgrade-popup .swal2-popup .swal2-content .wp-mail-smtp-button{text-transform:uppercase}.wp-mail-smtp-swal.wp-mail-smtp-upgrade-popup .swal2-popup .swal2-content #swal2-content{text-align:center}.wp-mail-smtp-swal.wp-mail-smtp-upgrade-popup .swal2-popup .swal2-content #swal2-content .wp-mail-smtp-button-main{background-color:#ff982d}.wp-mail-smtp-swal.wp-mail-smtp-upgrade-popup .swal2-popup .swal2-content #swal2-content .wp-mail-smtp-button-main:focus,.wp-mail-smtp-swal.wp-mail-smtp-upgrade-popup .swal2-popup .swal2-content #swal2-content .wp-mail-smtp-button-main:hover{background-color:#f97f00}.wp-mail-smtp-swal.wp-mail-smtp-upgrade-popup .swal2-popup .swal2-content .upgrade-bonus{position:relative;background:#faffac;margin:40px -50px 10px;padding:24px 60px 20px}.wp-mail-smtp-swal.wp-mail-smtp-upgrade-popup .swal2-popup .swal2-content .upgrade-bonus .icon-container{position:absolute;background:#2ecc71;color:#fff;width:46px;height:46px;border-radius:50%;left:calc(50% - 23px);top:-23px;border:6px solid #fff}.wp-mail-smtp-swal.wp-mail-smtp-upgrade-popup .swal2-popup .swal2-content .upgrade-bonus .icon-container .icon{position:absolute;top:10px;left:10px}.wp-mail-smtp-swal.wp-mail-smtp-upgrade-popup .swal2-popup .swal2-content .upgrade-bonus .highlight{color:#2ecc71;font-weight:500}.wp-mail-smtp-swal.wp-mail-smtp-upgrade-popup .swal2-popup .swal2-content .already-purchased{font-size:14px;color:#888}.wp-mail-smtp-swal.wp-mail-smtp-upgrade-popup .swal2-popup .swal2-content .already-purchased:focus,.wp-mail-smtp-swal.wp-mail-smtp-upgrade-popup .swal2-popup .swal2-content .already-purchased:hover{color:#555}.wp-mail-smtp-swal.wp-mail-smtp-swal-plugin-upgrade .swal2-popup .swal2-header{margin:20px}.wp-mail-smtp-swal.wp-mail-smtp-swal-plugin-upgrade .swal2-popup .swal2-content{padding:0 20px;margin-bottom:30px}.wp-mail-smtp-swal.wp-mail-smtp-swal-plugin-upgrade .swal2-popup .swal2-content .subtitle{margin:0 0 45px}.wp-mail-smtp-swal.wp-mail-smtp-swal-plugin-upgrade .swal2-popup .swal2-content .title-container{margin-bottom:7px}.wp-mail-smtp-swal.wp-mail-smtp-swal-plugin-upgrade .swal2-popup .swal2-content .bonus{padding:30px;margin:17px -30px 0;background-color:#fefcca;color:#222;border-radius:3px;text-align:center}.wp-mail-smtp-swal.wp-mail-smtp-swal-plugin-upgrade .swal2-popup .swal2-actions{-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end}.wp-mail-smtp-swal.wp-mail-smtp-swal-plugin-upgrade .swal2-popup .swal2-actions .swal2-styled.swal2-confirm{background-color:#6aa08b}.wp-mail-smtp-swal.wp-mail-smtp-swal-plugin-upgrade .swal2-popup .swal2-actions .swal2-styled.swal2-confirm:focus,.wp-mail-smtp-swal.wp-mail-smtp-swal-plugin-upgrade .swal2-popup .swal2-actions .swal2-styled.swal2-confirm:hover{background-color:#548371}.wp-mail-smtp-swal.wp-mail-smtp-swal-plugin-upgrade .swal2-popup .swal2-actions .swal2-styled.swal2-cancel:before,.wp-mail-smtp-swal.wp-mail-smtp-swal-plugin-upgrade .swal2-popup .swal2-actions .swal2-styled.swal2-confirm:after{content:none}.wp-mail-smtp-swal.wp-mail-smtp-swal-plugin-upgrade .swal2-popup .settings-input-long-checkbox .checkbox.checkbox-checked:after{top:5px}.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback-good .swal2-popup .swal2-content{margin-bottom:27px}.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback-good .swal2-popup .swal2-content img.icon{color:#fdb72c;width:16px;vertical-align:middle}.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback-good .swal2-popup .swal2-actions{border-top:none;padding:0 50px 40px}.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback-bad .swal2-popup .swal2-content{margin-bottom:16px}.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback-bad .swal2-popup .swal2-content textarea{border:1px solid #b6b6b6;color:#222;border-radius:3px;margin:27px 0 11px;padding:10px;font-size:16px;width:100%}.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback-bad .swal2-popup .swal2-content textarea:focus{outline:none;border:1px solid #2d4f60;-webkit-box-shadow:0 0 0 1px #2d4f60;box-shadow:0 0 0 1px #2d4f60}.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback-bad .swal2-popup .swal2-content .permission-container{display:-webkit-box;display:-ms-flexbox;display:flex}.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback-bad .swal2-popup .swal2-content .permission-container label{font-size:14px;margin-left:7px}.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback-bad .swal2-popup .swal2-content .permission-container input[type=checkbox]{width:16px;height:16px}.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback-bad .swal2-popup .swal2-actions{border-top:none;padding:0 50px 40px}.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback-bad .swal2-popup .swal2-actions .swal2-styled.swal2-confirm:after{content:none}.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback .swal2-popup .swal2-content{margin-bottom:47px}.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback .swal2-popup .swal2-actions{border-top:none;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;padding:0 30px 40px}.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback .swal2-popup .swal2-actions .swal2-styled.swal2-cancel,.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback .swal2-popup .swal2-actions .swal2-styled.swal2-confirm{width:128px;height:128px;padding:0;font-size:0;text-indent:-9999px;-webkit-box-shadow:none;box-shadow:none}.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback .swal2-popup .swal2-actions .swal2-styled.swal2-cancel:after,.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback .swal2-popup .swal2-actions .swal2-styled.swal2-cancel:before,.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback .swal2-popup .swal2-actions .swal2-styled.swal2-confirm:after,.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback .swal2-popup .swal2-actions .swal2-styled.swal2-confirm:before{content:none}.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback .swal2-popup .swal2-actions .swal2-styled.swal2-confirm{background:url(../img/thumbs-up.svg);margin-right:50px}.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback .swal2-popup .swal2-actions .swal2-styled.swal2-confirm:hover{background:url(../img/thumbs-up-hover.svg)}.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback .swal2-popup .swal2-actions .swal2-styled.swal2-cancel{background:url(../img/thumbs-down.svg)!important}.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback .swal2-popup .swal2-actions .swal2-styled.swal2-cancel:hover{background:url(../img/thumbs-down-hover.svg)!important}.wp-mail-smtp-swal.wp-mail-smtp-swal-error .swal2-popup p{margin:0}.wp-mail-smtp-swal.wp-mail-smtp-swal-error .swal2-popup .swal2-content{padding:0 40px;margin-bottom:29px}.wp-mail-smtp-swal.wp-mail-smtp-swal-error .swal2-popup .swal2-content .subtitle{margin:0 0 26px}.wp-mail-smtp-swal.wp-mail-smtp-swal-error .swal2-popup .swal2-content .detailed-error{padding:11px 15px;font-size:14px;line-height:20px;margin:0;color:#555;border:1px solid #ddd;border-left:4px solid #dc3232;text-align:left;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.07);box-shadow:0 1px 1px rgba(0,0,0,.07)}.wp-mail-smtp-swal.wp-mail-smtp-swal-error .swal2-popup .swal2-content .detailed-error h3{font-size:14px;color:#222;font-weight:500;line-height:23px;margin:0}.wp-mail-smtp-swal.wp-mail-smtp-swal-error .swal2-popup .swal2-actions{padding:0 50px 40px;border-top:none}.wp-mail-smtp-swal.wp-mail-smtp-swal-error .swal2-popup .swal2-actions .swal2-styled.swal2-confirm:after{content:none}.wp-mail-smtp-swal.wp-mail-smtp-swal-alert .swal2-popup .swal2-header{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.wp-mail-smtp-swal.wp-mail-smtp-swal-alert .swal2-popup .swal2-content{padding:0 40px;margin-bottom:29px}.wp-mail-smtp-swal.wp-mail-smtp-swal-alert .swal2-popup .swal2-content #swal2-content{text-align:center}.wp-mail-smtp-swal.wp-mail-smtp-swal-alert .swal2-popup .swal2-content p{margin:0 0 26px}.wp-mail-smtp-swal.wp-mail-smtp-swal-alert .swal2-popup .swal2-actions{padding:0 50px 40px;border-top:none;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.wp-mail-smtp-swal.wp-mail-smtp-swal-alert .swal2-popup .swal2-actions .swal2-styled.swal2-confirm:after{content:none}.wp-mail-smtp-setup-wizard-step .license-form{color:#222}.wp-mail-smtp-setup-wizard-step .license-form input{display:block;width:100%;height:40px;font-size:16px;padding:10px;color:#222;border:1px solid #999;border-radius:3px}.wp-mail-smtp-setup-wizard-step .license-form input:focus{outline:none;border:1px solid #2d4f60;-webkit-box-shadow:0 0 0 1px #2d4f60;box-shadow:0 0 0 1px #2d4f60}.wp-mail-smtp-setup-wizard-step .license-form button{-ms-flex-negative:0;flex-shrink:0;margin-top:10px;width:100%}.wp-mail-smtp-setup-wizard-step .license-form .license-control{display:block}.wp-mail-smtp-setup-wizard-step .license-form.license-form-error input{border-color:#dc3232}.wp-mail-smtp-setup-wizard-step .license-form.license-form-error .error-message{color:#dc3232;font-size:14px;margin:5px 0 0}.wp-mail-smtp-setup-wizard-step .license-form p{margin:0 0 16px}.wp-mail-smtp-setup-wizard-step-configure-mailer .license-form p{font-size:16px;line-height:24px;color:#222}.wp-mail-smtp-setup-wizard-step-configure-mailer-settings{margin-top:29px}.wp-mail-smtp-setup-wizard-step-configure-mailer-settings.wp-mail-smtp-setup-wizard-step-configure-mailer-settings-smtp .mailer-description a{font-weight:500}.wp-mail-smtp-setup-wizard-step-configure-mailer-settings .mailer-description{font-size:16px;line-height:24px;color:#222;margin-bottom:29px}.wp-mail-smtp-setup-wizard-step-configure-mailer-settings .mailer-description-links{margin-top:0}.wp-mail-smtp-setup-wizard-step-configure-mailer-settings .mailer-description-links a{margin-right:20px}.wp-mail-smtp-setup-wizard-step-configure-mailer-settings .mailer-description-links a.wp-mail-smtp-link-docs,.wp-mail-smtp-setup-wizard-step-configure-mailer-settings .mailer-description-links a:last-child{margin-top:10px;display:block}.wp-mail-smtp-setup-wizard-step-configure-mailer-settings .mailer-description-links .wp-mail-smtp-link{font-weight:500}.wp-mail-smtp-setup-wizard-step-configure-mailer-settings .mailer-description-links .mailer-offer-link-disclosure{text-decoration:underline;text-decoration-style:dotted;font-size:14px;display:inline-block;cursor:help;margin-top:15px;color:#777}.wp-mail-smtp-setup-wizard-step-configure-mailer .wp-mail-smtp-configure-mailer-header{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.wp-mail-smtp-setup-wizard-step-configure-mailer .wp-mail-smtp-configure-mailer-header-container{width:calc(100% - 94px)}.wp-mail-smtp-setup-wizard-step-configure-mailer .wp-mail-smtp-configure-mailer-logo{width:94px;height:94px;border:1px solid #e6e6e6;border-radius:50%;position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.wp-mail-smtp-setup-wizard-step-configure-mailer .wp-mail-smtp-configure-mailer-logo svg{width:55px}.wp-mail-smtp-setup-wizard-step-configure-mailer .wp-mail-smtp-gmail-one-click-setup-switch{margin-bottom:30px}.wp-mail-smtp-setup-wizard-step-configure-mailer .wp-mail-smtp-gmail-one-click-setup-switch .label{font-size:16px}.settings-amazon-ses-identities,.settings-input-checkbox,.settings-input-long-checkbox,.settings-input-number,.settings-input-radio,.settings-input-select,.settings-input-switch,.settings-input-text,.settings-oauth-connection{margin:0 0 29px}.settings-amazon-ses-identities:last-child,.settings-input-checkbox:last-child,.settings-input-long-checkbox:last-child,.settings-input-number:last-child,.settings-input-radio:last-child,.settings-input-select:last-child,.settings-input-switch:last-child,.settings-input-text:last-child,.settings-oauth-connection:last-child{margin-bottom:20px}.settings-amazon-ses-identities .settings-input-label-container,.settings-input-checkbox .settings-input-label-container,.settings-input-long-checkbox .settings-input-label-container,.settings-input-number .settings-input-label-container,.settings-input-radio .settings-input-label-container,.settings-input-select .settings-input-label-container,.settings-input-switch .settings-input-label-container,.settings-input-text .settings-input-label-container,.settings-oauth-connection .settings-input-label-container{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin:0 0 12px}.settings-amazon-ses-identities .label,.settings-input-checkbox .label,.settings-input-long-checkbox .label,.settings-input-number .label,.settings-input-radio .label,.settings-input-select .label,.settings-input-switch .label,.settings-input-text .label,.settings-oauth-connection .label{color:#222;display:inline-block;line-height:21px;font-weight:500;font-size:18px}.settings-amazon-ses-identities .wp-mail-smtp-info,.settings-input-checkbox .wp-mail-smtp-info,.settings-input-long-checkbox .wp-mail-smtp-info,.settings-input-number .wp-mail-smtp-info,.settings-input-radio .wp-mail-smtp-info,.settings-input-select .wp-mail-smtp-info,.settings-input-switch .wp-mail-smtp-info,.settings-input-text .wp-mail-smtp-info,.settings-oauth-connection .wp-mail-smtp-info{margin-left:10px}.settings-amazon-ses-identities .error,.settings-input-checkbox .error,.settings-input-long-checkbox .error,.settings-input-number .error,.settings-input-radio .error,.settings-input-select .error,.settings-input-switch .error,.settings-input-text .error,.settings-oauth-connection .error{display:-webkit-box;display:-ms-flexbox;display:flex;color:#dc3232;font-size:14px}.settings-amazon-ses-identities .error .icon,.settings-input-checkbox .error .icon,.settings-input-long-checkbox .error .icon,.settings-input-number .error .icon,.settings-input-radio .error .icon,.settings-input-select .error .icon,.settings-input-switch .error .icon,.settings-input-text .error .icon,.settings-oauth-connection .error .icon{margin-right:10px}.settings-amazon-ses-identities.input-error input,.settings-input-checkbox.input-error input,.settings-input-long-checkbox.input-error input,.settings-input-number.input-error input,.settings-input-radio.input-error input,.settings-input-select.input-error input,.settings-input-switch.input-error input,.settings-input-text.input-error input,.settings-oauth-connection.input-error input{border-color:#dc3232}.settings-amazon-ses-identities input:disabled,.settings-input-checkbox input:disabled,.settings-input-long-checkbox input:disabled,.settings-input-number input:disabled,.settings-input-radio input:disabled,.settings-input-select input:disabled,.settings-input-switch input:disabled,.settings-input-text input:disabled,.settings-oauth-connection input:disabled{cursor:not-allowed}.settings-amazon-ses-identities .description,.settings-input-checkbox .description,.settings-input-long-checkbox .description,.settings-input-number .description,.settings-input-radio .description,.settings-input-select .description,.settings-input-switch .description,.settings-input-text .description,.settings-oauth-connection .description{font-size:14px;line-height:20px;color:#555;margin:-4px 0 0}.settings-amazon-ses-identities .description--constant,.settings-input-checkbox .description--constant,.settings-input-long-checkbox .description--constant,.settings-input-number .description--constant,.settings-input-radio .description--constant,.settings-input-select .description--constant,.settings-input-switch .description--constant,.settings-input-text .description--constant,.settings-oauth-connection .description--constant{font-size:12px;margin-top:5px}.settings-input-number input,.settings-input-text input{display:block;width:100%;height:40px;font-size:16px;padding:10px;color:#222;border:1px solid #999;border-radius:3px;margin:0 0 15px}.settings-input-number input:focus,.settings-input-text input:focus{outline:none;border:1px solid #2d4f60;-webkit-box-shadow:0 0 0 1px #2d4f60;box-shadow:0 0 0 1px #2d4f60}.settings-input-number input::-webkit-input-placeholder,.settings-input-text input::-webkit-input-placeholder{color:#888}.settings-input-number input::-moz-placeholder,.settings-input-text input::-moz-placeholder{color:#888}.settings-input-number input:-ms-input-placeholder,.settings-input-text input:-ms-input-placeholder{color:#888}.settings-input-number input::-ms-input-placeholder,.settings-input-text input::-ms-input-placeholder{color:#888}.settings-input-number input::placeholder,.settings-input-text input::placeholder{color:#888}.settings-input-number-error input,.settings-input-text-error input{border-color:#dc3232}.settings-input-number.settings-input-text-with-copy .settings-input-container,.settings-input-text.settings-input-text-with-copy .settings-input-container{display:-webkit-box;display:-ms-flexbox;display:flex;margin-bottom:15px}.settings-input-number.settings-input-text-with-copy .settings-input-container input,.settings-input-text.settings-input-text-with-copy .settings-input-container input{color:#888;margin-bottom:0}.settings-input-number.settings-input-text-with-copy .settings-input-container .wp-mail-smtp-button,.settings-input-text.settings-input-text-with-copy .settings-input-container .wp-mail-smtp-button{outline:none;margin:0 0 0 10px;background-color:#999}.settings-input-number.settings-input-text-with-copy .settings-input-container .wp-mail-smtp-button:hover,.settings-input-text.settings-input-text-with-copy .settings-input-container .wp-mail-smtp-button:hover{background-color:#888}.settings-input-number.settings-input-text-with-copy .settings-input-container .wp-mail-smtp-button-small,.settings-input-text.settings-input-text-with-copy .settings-input-container .wp-mail-smtp-button-small{padding:8px 12px}.settings-input-number.settings-input-text-with-copy .settings-input-container .wp-mail-smtp-button-copied,.settings-input-number.settings-input-text-with-copy .settings-input-container .wp-mail-smtp-button-copied:hover,.settings-input-text.settings-input-text-with-copy .settings-input-container .wp-mail-smtp-button-copied,.settings-input-text.settings-input-text-with-copy .settings-input-container .wp-mail-smtp-button-copied:hover{background-color:#6aa08b}.settings-input-number.settings-input-text-with-copy .settings-input-container .wp-mail-smtp-button .copy-button-container,.settings-input-text.settings-input-text-with-copy .settings-input-container .wp-mail-smtp-button .copy-button-container{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.settings-input-number.settings-input-text-with-copy .settings-input-container .wp-mail-smtp-button .copy-button-container .icon,.settings-input-text.settings-input-text-with-copy .settings-input-container .wp-mail-smtp-button .copy-button-container .icon{display:none}.settings-input-number.settings-input-text-with-copy .settings-input-container .wp-mail-smtp-button .copy-button-container .icon.active,.settings-input-text.settings-input-text-with-copy .settings-input-container .wp-mail-smtp-button .copy-button-container .icon.active{display:block}.settings-input-radio input{opacity:0;position:absolute}.settings-input-radio label{color:#222;font-size:14px;display:inline-block;margin:0 30px 15px 0}.settings-input-radio label:last-child{margin-right:0}.settings-input-radio label>span{vertical-align:middle}.settings-input-radio label.wp-mail-smtp-styled-radio-label-disabled{cursor:not-allowed}.settings-input-radio .wp-mail-smtp-styled-radio{width:20px;height:20px;border:1px solid #999;position:relative;display:inline-block;border-radius:50%;margin-right:10px}.settings-input-radio .wp-mail-smtp-styled-radio.wp-mail-smtp-styled-radio-checked{border-color:#2d4f60}.settings-input-radio .wp-mail-smtp-styled-radio.wp-mail-smtp-styled-radio-checked:after{left:2px;right:2px;top:2px;bottom:2px;position:absolute;content:"";background:#2d4f60;display:block;border-radius:50%}.settings-input-radio .wp-mail-smtp-styled-radio.wp-mail-smtp-styled-radio-disabled{opacity:.4}.settings-input-radio input:focus-visible+.wp-mail-smtp-styled-radio{-webkit-box-shadow:0 0 0 1px #999;box-shadow:0 0 0 1px #999}.settings-input-radio input:focus-visible+.wp-mail-smtp-styled-radio.wp-mail-smtp-styled-radio-checked{-webkit-box-shadow:0 0 0 1px #2d4f60;box-shadow:0 0 0 1px #2d4f60}.settings-input-switch.sub_setting{background-color:#f8f8f8;padding:20px;margin-top:-17px}.settings-input-switch.sub_setting .label{font-size:14px}.settings-input-switch.sub_setting .label-description{color:#555}.settings-input-switch .title{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.settings-input-switch .title .wp-mail-smtp-pro-badge{margin-left:10px;height:18px;width:auto}.settings-input-switch .control{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.settings-input-switch input{position:absolute;top:auto;overflow:hidden;clip:rect(1px,1px,1px,1px);width:1px;height:1px;white-space:nowrap}.settings-input-switch input:checked+.toggle-switch{background-color:#2d4f60}.settings-input-switch input:checked+.toggle-switch:before{-webkit-transform:translateX(10px);-ms-transform:translateX(10px);transform:translateX(10px)}.settings-input-switch input:disabled:checked:hover+.toggle-switch,.settings-input-switch input:disabled:not(:checked):hover+.toggle-switch{-webkit-box-shadow:none;box-shadow:none}.settings-input-switch input:disabled:not(:checked):hover+.toggle-switch{background-color:#ddd}.settings-input-switch input:disabled+.toggle-switch{background-color:#ddd;cursor:not-allowed}.settings-input-switch input:disabled:checked+.toggle-switch{background-color:#4e88a5;cursor:not-allowed}.settings-input-switch input:checked:focus+.toggle-switch,.settings-input-switch input:checked:hover+.toggle-switch{-webkit-box-shadow:0 0 0 1px #fff,0 0 0 3px #2d4f60;box-shadow:0 0 0 1px #fff,0 0 0 3px #2d4f60}.settings-input-switch input:not(:checked):focus+.toggle-switch,.settings-input-switch input:not(:checked):hover+.toggle-switch{background-color:#999;-webkit-box-shadow:0 0 0 1px #fff,0 0 0 3px #999;box-shadow:0 0 0 1px #fff,0 0 0 3px #999}.settings-input-switch .toggle-switch{position:relative;cursor:pointer;background-color:#bbb;border-radius:10px;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out;vertical-align:middle;display:inline-block;width:30px;height:20px}.settings-input-switch .toggle-switch:before{position:absolute;content:"";height:16px;width:16px;left:2px;top:2px;background-color:#fff;border-radius:50%;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.settings-input-switch .description{margin-bottom:15px}.settings-input-switch .label-description{font-size:14px;line-height:20px;color:#222;margin:0 0 0 20px;-webkit-box-flex:1;-ms-flex:1;flex:1}.settings-input-select-container{position:relative;margin:0 0 15px}.settings-input-select-container:after{content:"";background:no-repeat url(../img/chevron-down-solid-grey.svg);right:10px;top:14px;width:12px;height:12px;position:absolute;pointer-events:none}.settings-input-select select::-ms-expand{display:none}.settings-input-select select{-webkit-appearance:none;-moz-appearance:none;appearance:none;display:block;width:100%;height:40px;font-size:16px;padding:8px 5px 8px 10px;color:#222;border:1px solid #999;border-radius:3px}.settings-input-select select:focus{outline:none;border:1px solid #2d4f60;-webkit-box-shadow:0 0 0 1px #2d4f60;box-shadow:0 0 0 1px #2d4f60}.settings-input-select select:disabled{cursor:not-allowed}.settings-input-select-error select{border-color:#dc3232}.settings-amazon-ses-identities>.wp-mail-smtp-loader{display:block}.settings-amazon-ses-identities p{margin:0 0 17px}.settings-amazon-ses-identities .description{margin-bottom:17px}.settings-amazon-ses-identities .ses-identities-container{background:#f8f8f8;padding:20px}.settings-amazon-ses-identities .ses-identities-table-container{border-radius:3px;font-size:14px;line-height:20px;text-align:left}.settings-amazon-ses-identities .ses-identities-table-container+.wp-mail-smtp-amazonses-identity-form{margin-top:20px}.settings-amazon-ses-identities .ses-identities-table-container table{width:100%;border-collapse:collapse}.settings-amazon-ses-identities .ses-identities-table-container th.ses-identity-column{color:#222;font-weight:500}.settings-amazon-ses-identities .ses-identities-table-container .ses-identity-column-sender{width:50%}.settings-amazon-ses-identities .ses-identities-table-container .ses-identity-column-status,.settings-amazon-ses-identities .ses-identities-table-container .ses-identity-column-type{width:25%}.settings-amazon-ses-identities .ses-identities-table-container tr{border-bottom:1px solid #ddd}.settings-amazon-ses-identities .ses-identities-table-container th{padding:0 0 20px}.settings-amazon-ses-identities .ses-identities-table-container td{padding:18px 0}.settings-amazon-ses-identities .ses-identities-table-container .wp-mail-smtp-button{margin-top:20px}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form{background:#f8f8f8;border-radius:3px}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form h3{font-size:14px;line-height:21px;margin-bottom:16px}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form p{font-size:14px;margin:0 0 20px}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form .settings-input-radio{margin-bottom:5px}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form .settings-input-text{margin-bottom:20px}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form .amazonses-identity-form-step .wp-mail-smtp-button-main.wp-mail-smtp-button-verify{min-width:150px}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form .amazonses-identity-form-step .ses-identities-email-success-notice{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin:0}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form .amazonses-identity-form-step .ses-identities-email-success-notice .icon{width:16px;height:16px;margin-right:10px;color:#6aa08b}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form .amazonses-identity-form-step-domain .settings-input-text{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form .amazonses-identity-form-step-domain .settings-input-text label{width:50px;margin-right:16px}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form .amazonses-identity-form-step-domain .settings-input-text label .label{font-size:16px;color:#888;font-weight:400;margin-bottom:0}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form .amazonses-identity-form-step-domain .settings-input-text .settings-input-container{width:100%}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form .amazonses-identity-form-step-domain .amazonses-dns-records{border:1px solid #ddd;border-radius:4px}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form .amazonses-identity-form-step-domain .amazonses-dns-records__row{display:-webkit-box;display:-ms-flexbox;display:flex;padding:7.5px}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form .amazonses-identity-form-step-domain .amazonses-dns-records__row--heading{border-radius:4px 4px 0 0;background-color:#eee}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form .amazonses-identity-form-step-domain .amazonses-dns-records__row--record{border-top:1px solid #ddd}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form .amazonses-identity-form-step-domain .amazonses-dns-records__col{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;-ms-flex-preferred-size:0;flex-basis:0;margin:7.5px}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form .amazonses-identity-form-step-domain .amazonses-dns-records__col--heading{font-size:14px;line-height:20px;font-weight:500;color:#444}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form .amazonses-identity-form-step-domain .amazonses-dns-records__col--record .settings-input-container{position:relative}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form .amazonses-identity-form-step-domain .amazonses-dns-records__col--record .settings-input-text{margin:0}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form .amazonses-identity-form-step-domain .amazonses-dns-records__col--record .settings-input-label-container{display:none}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form .amazonses-identity-form-step-domain .amazonses-dns-records__col--record input{margin:0;padding-right:39px}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form .amazonses-identity-form-step-domain .amazonses-dns-records__col--record button{position:absolute;right:1px;top:1px;bottom:1px;padding:9px 11px;margin:0;border:none;border-radius:0 1px 1px 0}.settings-oauth-connection .description{margin-bottom:20px}.settings-oauth-connection .wp-mail-smtp-button{margin-top:-2px}.settings-oauth-connection .remove-authorization-container .description .icon{color:#6aa08b;width:16px;height:16px;margin-left:10px}.settings-oauth-connection .remove-authorization-container .description.connected-as{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.settings-oauth-connection .remove-authorization-container .wp-mail-smtp-button{margin-top:-3px}.settings-input-long-checkbox{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:30px 0;border-bottom:1px solid #e6e6e6;cursor:pointer;margin-bottom:0}.settings-input-long-checkbox.settings-input-long-checkbox-disabled{cursor:not-allowed}.settings-input-long-checkbox .title-container{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin-bottom:9px}.settings-input-long-checkbox .title-container .wp-mail-smtp-pro-badge{margin-left:10px;width:46px;height:26px}.settings-input-long-checkbox .description{margin-right:30px}.settings-input-long-checkbox .label{margin:0}.settings-input-long-checkbox input{opacity:0;position:absolute}.settings-input-long-checkbox .checkbox{width:32px;height:32px;position:relative;display:inline-block;border-radius:50%;background-color:#e6e6e6}.settings-input-long-checkbox .checkbox .icon{display:none}.settings-input-long-checkbox .checkbox.checkbox-checked{background-color:#2d4f60;color:#fff}.settings-input-long-checkbox .checkbox.checkbox-checked .icon{display:block;position:absolute;left:8px;top:8px}.settings-input-long-checkbox .checkbox.checkbox-checked.checkbox-disabled{background-color:#6aa08b}.settings-input-long-checkbox:first-child{padding-top:0;color:red}.settings-input-long-checkbox:last-child{border-bottom:none;margin-bottom:0}.settings-input-long-checkbox input:focus-visible+.checkbox{-webkit-box-shadow:0 0 0 1px #fff,0 0 0 3px #e6e6e6;box-shadow:0 0 0 1px #fff,0 0 0 3px #e6e6e6}.settings-input-long-checkbox input:focus-visible+.checkbox.checkbox-checked{-webkit-box-shadow:0 0 0 1px #fff,0 0 0 3px #2d4f60;box-shadow:0 0 0 1px #fff,0 0 0 3px #2d4f60}.settings-input-checkbox input{opacity:0;position:absolute}.settings-input-checkbox .settings-input-checkbox-container{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.settings-input-checkbox .settings-input-checkbox-container .input-label{margin-left:10px}.settings-input-checkbox .checkbox{width:24px;height:24px;position:relative;display:inline-block;border-radius:3px;border:1px solid #999;background-color:#fff}.settings-input-checkbox .checkbox .icon{display:none}.settings-input-checkbox .checkbox.checkbox-checked{background-color:#2d4f60;border:none;color:#fff}.settings-input-checkbox .checkbox.checkbox-checked .icon{display:block;position:absolute;left:5px;top:5px}.settings-input-checkbox .checkbox.checkbox-checked.checkbox-disabled{background-color:#4e88a5}.settings-input-checkbox input:focus-visible+.checkbox{-webkit-box-shadow:0 0 0 1px #999;box-shadow:0 0 0 1px #999}.settings-input-checkbox input:focus-visible+.checkbox.checkbox-checked{-webkit-box-shadow:0 0 0 1px #fff,0 0 0 3px #2d4f60;box-shadow:0 0 0 1px #fff,0 0 0 3px #2d4f60}.wp-mail-smtp-setup-wizard-step-plugin-features .wp-mail-smtp-plugin-features-header{margin-bottom:33px}.wp-mail-smtp-setup-wizard-step-plugin-features .wp-mail-smtp-plugin-features-header .wp-mail-smtp-content-header{margin-bottom:0}.wp-mail-smtp-setup-wizard-step-license .upgrade-content,.wp-mail-smtp-setup-wizard-step-license .verified-license{background-color:#e6efec;border-radius:3px;padding:30px;margin-bottom:50px;color:#222}.wp-mail-smtp-setup-wizard-step-license .upgrade-content p{margin:0 0 30px}.wp-mail-smtp-setup-wizard-step-license .verified-license{text-align:center;margin-bottom:20px}.wp-mail-smtp-setup-wizard-step-license .checked-item-list .checked-item{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;font-size:18px;margin-bottom:15px}.wp-mail-smtp-setup-wizard-step-license .checked-item-list .checked-item:last-child{margin-bottom:0}.wp-mail-smtp-setup-wizard-step-license .checked-item-list .checked-item .icon{color:#6aa08b;margin-right:15px;width:16px}.wp-mail-smtp-setup-wizard-step-license .checked-item-list .checked-item>span{width:calc(100% - 31px)}.wp-mail-smtp-setup-wizard-check-configuration .check-configuration-loading-image-container{text-align:center}.wp-mail-smtp-plugin-item{border:1px solid #ddd;border-radius:3px;padding:10px;margin-bottom:20px;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;color:#222}.wp-mail-smtp-plugin-item,.wp-mail-smtp-plugin-item-title-container{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.wp-mail-smtp-plugin-item-title-container{margin-bottom:10px}.wp-mail-smtp-plugin-item .wp-mail-smtp-button{height:32px;width:120px;text-align:center;font-size:13px;line-height:16px;font-weight:500;padding:8px 31px;color:#fff;background-color:#6693af}.wp-mail-smtp-plugin-item .wp-mail-smtp-button:hover{background-color:#2d4f60}.wp-mail-smtp-plugin-item .wp-mail-smtp-button:disabled{cursor:not-allowed;background-color:#e6e6e6;color:#777}.wp-mail-smtp-plugin-item:last-child{margin-bottom:0}.wp-mail-smtp-setup-wizard-configuration-success .plugin-item-container{margin-bottom:20px}.wp-mail-smtp-setup-wizard-configuration-success .plugin-item-container .medium-bold{color:#222;margin-bottom:20px}.wp-mail-smtp-setup-wizard-configuration-success .upgrade-banner-container{margin:30px -20px 0}.wp-mail-smtp-setup-wizard-configuration-success .upgrade-banner{padding:30px;border-radius:3px 3px 0 0;text-align:center;background-color:#ecf3f1}.wp-mail-smtp-setup-wizard-configuration-success .upgrade-banner .wp-mail-smtp-setup-wizard-content h2{margin-bottom:10px}.wp-mail-smtp-setup-wizard-configuration-success .upgrade-banner .subtitle{margin-bottom:28px}.wp-mail-smtp-setup-wizard-configuration-success .upgrade-banner .checked-item-list{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;margin-bottom:29px;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.wp-mail-smtp-setup-wizard-configuration-success .upgrade-banner .checked-item-list .checked-item{margin-bottom:10px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;font-size:18px;color:#222}.wp-mail-smtp-setup-wizard-configuration-success .upgrade-banner .checked-item-list .checked-item .icon{color:#6aa08b;margin-right:8px}.wp-mail-smtp-setup-wizard-configuration-success .bonus{margin:10px 0 0;padding:30px;background-color:#fefcca;color:#222;border-radius:0 0 3px 3px;text-align:center}.wp-mail-smtp-setup-wizard-configuration-success .wp-mail-smtp-setup-wizard-step-footer{margin:20px 0}.wp-mail-smtp-setup-wizard-configuration-success .wp-mail-smtp-setup-wizard-step-footer button{margin-bottom:10px;width:100%}.wp-mail-smtp-setup-wizard-configuration-success .wp-mail-smtp-setup-wizard-step-footer button:last-child{margin-bottom:0}.wp-mail-smtp-setup-wizard-content .wp-mail-smtp-setup-wizard-configuration-failure .wp-mail-smtp-content-header{margin-bottom:27px}.wp-mail-smtp-setup-wizard-configuration-failure .start-troubleshooting-arrow-container{margin-bottom:11px}.wp-mail-smtp-setup-wizard-configuration-failure .start-troubleshooting-arrow-container svg{width:112px;height:112px;margin:0 auto;display:block}.wp-mail-smtp-setup-wizard-configuration-failure .wp-mail-smtp-setup-wizard-step-footer{margin:20px 0}.wp-mail-smtp-setup-wizard-configuration-failure .wp-mail-smtp-setup-wizard-step-footer .wp-mail-smtp-button{margin-bottom:10px;width:100%}.wp-mail-smtp-setup-wizard-configuration-failure .wp-mail-smtp-setup-wizard-step-footer .wp-mail-smtp-button:last-child{margin-bottom:0}.wp-mail-smtp-admin-page{position:relative}.wp-mail-smtp-admin-page .wp-mail-smtp-blocked,.wp-mail-smtp-admin-page .wp-mail-smtp-loading{position:fixed;top:0;bottom:0;right:0;left:0;background:rgba(68,68,68,.5);z-index:999}.wp-mail-smtp-admin-page .wp-mail-smtp-loading{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.swal2-shown .swal2-container.swal2-backdrop-show{background:rgba(68,68,68,.5)}img{max-width:100%}a{color:#6693af}a:focus,a:hover{text-decoration:none}a .text-with-arrow{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}a .text-with-arrow-right .icon{margin-left:10px}a .text-with-arrow-left .icon{margin-right:10px}.wp-mail-smtp-notice{padding:15px;font-size:14px;line-height:20px;margin:0;color:#222;border:1px solid #ddd;border-left:4px solid #00a0d2;text-align:left;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.07);box-shadow:0 1px 1px rgba(0,0,0,.07)}.wp-mail-smtp-notice--error{border-left:4px solid #dc3232}.wp-mail-smtp-notice--info{border-left:4px solid #00a0d2}.wp-mail-smtp-notice p{margin-top:0}.wp-mail-smtp-notice p:last-child{margin-bottom:0}.wp-mail-smtp-one-click-sign-in-btn{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:0;border:none;background-color:#4285f4;border-radius:2px;-webkit-box-shadow:0 2px 4px 0 rgba(0,0,0,.25);box-shadow:0 2px 4px 0 rgba(0,0,0,.25);-webkit-transition:-webkit-box-shadow .3s ease-in-out;transition:-webkit-box-shadow .3s ease-in-out;transition:box-shadow .3s ease-in-out;transition:box-shadow .3s ease-in-out,-webkit-box-shadow .3s ease-in-out;text-decoration:none;cursor:pointer;color:#fff}.wp-mail-smtp-one-click-sign-in-btn:hover{-webkit-box-shadow:0 0 3px 3px rgba(66,133,244,.3);box-shadow:0 0 3px 3px rgba(66,133,244,.3)}.wp-mail-smtp-one-click-sign-in-btn:active{background:#3367d6}.wp-mail-smtp-one-click-sign-in-btn--disabled,.wp-mail-smtp-one-click-sign-in-btn:disabled{pointer-events:none;background-color:#d4d3d3;-webkit-box-shadow:none;box-shadow:none;color:#7f7f7f}.wp-mail-smtp-one-click-sign-in-btn--disabled .wp-mail-smtp-one-click-sign-in-icon__bg,.wp-mail-smtp-one-click-sign-in-btn--disabled .wp-mail-smtp-one-click-sign-in-icon__border,.wp-mail-smtp-one-click-sign-in-btn:disabled .wp-mail-smtp-one-click-sign-in-icon__bg,.wp-mail-smtp-one-click-sign-in-btn:disabled .wp-mail-smtp-one-click-sign-in-icon__border{fill:#d4d3d3}.wp-mail-smtp-one-click-sign-in-btn--disabled .wp-mail-smtp-one-click-sign-in-icon__symbol,.wp-mail-smtp-one-click-sign-in-btn:disabled .wp-mail-smtp-one-click-sign-in-icon__symbol{fill:#7f7f7f}.wp-mail-smtp-one-click-sign-in-btn__icon{overflow:hidden;border-radius:2px}.wp-mail-smtp-one-click-sign-in-btn__icon svg{display:block;margin:-3px}.wp-mail-smtp-one-click-sign-in-btn__text{font-size:14px;font-weight:600;margin:0 10px}@media(min-width:782px){.wp-mail-smtp-setup-wizard-container{max-width:100%;margin:0 auto;width:850px}.wp-mail-smtp-setup-wizard-content{margin:50px 0 48px}.wp-mail-smtp-setup-wizard-content .wp-mail-smtp-content-header{margin-bottom:47px}.wp-mail-smtp-setup-wizard-content-container{padding:49px 100px 30px}.wp-mail-smtp-setup-wizard-content-container-container{padding:30px 20px}.wp-mail-smtp-setup-wizard-step-plugin-features .wp-mail-smtp-setup-wizard-content-container{padding:49px 100px 19px}.wp-mail-smtp-setup-wizard-content .wp-mail-smtp-separator{margin:30px 0}.wp-mail-smtp-setup-wizard-content .wp-mail-smtp-separator-no-margin{margin:0}.wp-mail-smtp-setup-wizard-content .wp-mail-smtp-separator-big-margin{margin:50px 0}.wp-mail-smtp-setup-wizard-step .license-form .license-control{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.wp-mail-smtp-setup-wizard-step .license-form input{width:calc(100% - 195px)}.wp-mail-smtp-setup-wizard-step .license-form button{margin-top:0;width:180px;margin-left:15px}.wp-mail-smtp-welcome .wp-mail-smtp-logo{margin-top:158px;padding:0}.wp-mail-smtp-welcome .wp-mail-smtp-setup-wizard-container{width:650px}.wp-mail-smtp-welcome .wp-mail-smtp-setup-wizard-content{margin:42px 0 60px}.wp-mail-smtp-welcome .wp-mail-smtp-setup-wizard-content-container{padding:80px 65px}.wp-mail-smtp-welcome .wp-mail-smtp-setup-wizard-content-container .wp-mail-smtp-content-header{margin-bottom:36px}.wp-mail-smtp-setup-wizard-step-configure-mailer-settings{margin-top:49px}.wp-mail-smtp-setup-wizard-step-configure-mailer-settings .mailer-description{margin-bottom:49px}.wp-mail-smtp-setup-wizard-step-configure-mailer-settings .mailer-description-links{margin-top:-31px}.wp-mail-smtp-setup-wizard-step-configure-mailer-settings .mailer-description-links a.wp-mail-smtp-link-docs,.wp-mail-smtp-setup-wizard-step-configure-mailer-settings .mailer-description-links a:last-child{margin-top:0;display:inline-block}.wp-mail-smtp-setup-wizard-step-configure-mailer .wp-mail-smtp-one-click-setup-switch{margin-bottom:50px}.wp-mail-smtp-setup-wizard-check-configuration .wp-mail-smtp-setup-wizard-content-container{padding:83px 100px 66px}.wp-mail-smtp-setup-wizard-check-configuration .wp-mail-smtp-setup-wizard-content-container .wp-mail-smtp-content-header{margin-bottom:55px}.wp-mail-smtp-setup-wizard-step-plugin-features .wp-mail-smtp-plugin-features-header{margin-bottom:53px}.wp-mail-smtp-input-radios-with-icons{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-ms-flex-wrap:wrap;flex-wrap:wrap}.wp-mail-smtp-input-radios-with-icons label{width:calc(50% - 10px)}.wp-mail-smtp-setup-wizard-timeline{padding:0}.wp-mail-smtp-setup-wizard-timeline .wp-mail-smtp-setup-wizard-timeline-step-line{margin:0 10px}.wp-mail-smtp-setup-wizard-step-footer{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:0;margin-top:0}.wp-mail-smtp-setup-wizard-step-footer-buttons{margin-bottom:0;margin-right:30px}.wp-mail-smtp-setup-wizard-step-footer-buttons button{margin-bottom:0;margin-right:15px;width:inherit}.wp-mail-smtp-setup-wizard-step-footer-buttons button:last-child{margin-right:0}.wp-mail-smtp-setup-wizard-form-row-highlight{padding:20px 20px 0}.wp-mail-smtp-setup-wizard-form-row-highlight .wp-mail-smtp-input-radios-with-icons label:last-child{margin-bottom:20px}.wp-mail-smtp-setup-wizard-configuration-failure .start-troubleshooting-arrow-container svg{margin:0;display:inline-block}.wp-mail-smtp-setup-wizard-configuration-failure .wp-mail-smtp-setup-wizard-step-footer{margin:0 30px}.wp-mail-smtp-setup-wizard-configuration-failure .wp-mail-smtp-setup-wizard-step-footer .wp-mail-smtp-button{margin-bottom:0;-webkit-box-flex:10;-ms-flex:10;flex:10}.wp-mail-smtp-setup-wizard-configuration-failure .wp-mail-smtp-setup-wizard-step-footer .wp-mail-smtp-button.wp-mail-smtp-button-main{-webkit-box-flex:11;-ms-flex:11;flex:11;margin-right:30px}.wp-mail-smtp-setup-wizard-configuration-success .upgrade-banner-container{margin:50px -70px 0}.wp-mail-smtp-setup-wizard-configuration-success .upgrade-banner .checked-item-list{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;text-align:center}.wp-mail-smtp-setup-wizard-configuration-success .upgrade-banner .checked-item-list .checked-item{margin-bottom:0}.wp-mail-smtp-setup-wizard-configuration-success .wp-mail-smtp-setup-wizard-step-footer{margin:0 30px;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.wp-mail-smtp-setup-wizard-configuration-success .wp-mail-smtp-setup-wizard-step-footer button{-webkit-box-flex:10;-ms-flex:10;flex:10;margin-bottom:0;margin-right:30px}.wp-mail-smtp-setup-wizard-configuration-success .wp-mail-smtp-setup-wizard-step-footer button:last-child{margin-right:0}.wp-mail-smtp-setup-wizard-configuration-success .wp-mail-smtp-setup-wizard-step-footer button.wp-mail-smtp-button-main{-webkit-box-flex:11;-ms-flex:11;flex:11}.wp-mail-smtp-plugin-item{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.wp-mail-smtp-plugin-item-title-container{margin-bottom:0}.wp-mail-smtp-swal.wp-mail-smtp-swal-plugin-upgrade .swal2-popup .swal2-header{margin:75px 90px 18px}.wp-mail-smtp-swal.wp-mail-smtp-swal-plugin-upgrade .swal2-popup .swal2-content{padding:0 90px}.wp-mail-smtp-swal.wp-mail-smtp-swal-plugin-upgrade .swal2-popup .swal2-content .bonus{margin:17px -70px 0}.wp-mail-smtp-swal.wp-mail-smtp-swal-plugin-upgrade .swal2-popup .swal2-actions .swal2-styled.swal2-confirm{margin-left:30px}.wp-mail-smtp-setup-wizard-step-footer a{margin:0 0 0 30px}a .text-with-arrow{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}}.wp-mail-smtp-pro-badge[data-v-2d9202de]{float:right;margin-top:3px;width:46px;height:26px}.wp-mail-smtp-logo-icon[data-v-2d9202de]{width:32px;height:32px}.wp-mail-smtp-setup-wizard-step-count[data-v-44fd4a93]{margin:0 0 16px;font-size:14px;line-height:18px;color:#b6b6b6}.wp-mail-smtp-notice[data-v-099efe34]{margin-top:-20px;margin-bottom:30px}.wp-mail-smtp-info .icon[data-v-74a4d2ae]{color:#ccc}.wp-mail-smtp-logo-icon[data-v-2e2edfa6]{width:32px;height:32px;margin-right:10px}.wp-mail-smtp-notice[data-v-05d90eba],.wp-mail-smtp-notice[data-v-a87376ac]{margin-top:-23px;margin-bottom:20px}
\ No newline at end of file
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/css/wizard.rtl.min.css b/wp-content/plugins/wp-mail-smtp/assets/vue/css/wizard.rtl.min.css
new file mode 100755
index 00000000..20e5d052
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/css/wizard.rtl.min.css
@@ -0,0 +1 @@
+.wp-mail-smtp-tooltip{display:block!important;z-index:10000;max-width:350px}.wp-mail-smtp-tooltip .wp-mail-smtp-tooltip-inner{background:#2d4f60;color:#fff;border-radius:5px;padding:16px 20px;font-size:14px}.wp-mail-smtp-tooltip .wp-mail-smtp-tooltip-inner a{color:#fff;font-weight:700}.wp-mail-smtp-tooltip .wp-mail-smtp-tooltip-arrow{width:0;height:0;border-style:solid;position:absolute;margin:5px;border-color:#2d4f60;z-index:1}.wp-mail-smtp-tooltip[x-placement^=top]{padding-bottom:5px}.wp-mail-smtp-tooltip[x-placement^=top] .wp-mail-smtp-tooltip-arrow{border-width:5px 5px 0;border-right-color:rgba(0,0,0,0)!important;border-left-color:rgba(0,0,0,0)!important;border-bottom-color:rgba(0,0,0,0)!important;bottom:0;right:calc(50% - 5px);margin-top:0;margin-bottom:0}.wp-mail-smtp-tooltip[x-placement^=bottom]{padding-top:5px}.wp-mail-smtp-tooltip[x-placement^=bottom] .wp-mail-smtp-tooltip-arrow{border-width:0 5px 5px;border-right-color:rgba(0,0,0,0)!important;border-left-color:rgba(0,0,0,0)!important;border-top-color:rgba(0,0,0,0)!important;top:0;right:calc(50% - 5px);margin-top:0;margin-bottom:0}.wp-mail-smtp-tooltip[x-placement^=right]{padding-right:5px}.wp-mail-smtp-tooltip[x-placement^=right] .wp-mail-smtp-tooltip-arrow{border-width:5px 0 5px 5px;border-right-color:rgba(0,0,0,0)!important;border-top-color:rgba(0,0,0,0)!important;border-bottom-color:rgba(0,0,0,0)!important;right:0;top:calc(50% - 5px);margin-right:0;margin-left:0}.wp-mail-smtp-tooltip[x-placement^=left]{padding-left:5px}.wp-mail-smtp-tooltip[x-placement^=left] .wp-mail-smtp-tooltip-arrow{border-width:5px 5px 5px 0;border-top-color:rgba(0,0,0,0)!important;border-left-color:rgba(0,0,0,0)!important;border-bottom-color:rgba(0,0,0,0)!important;left:0;top:calc(50% - 5px);margin-right:0;margin-left:0}.wp-mail-smtp-tooltip.popover .popover-inner{background:#fff;color:#2d4f60;padding:24px;border-radius:5px;-webkit-box-shadow:0 5px 30px rgba(0,0,0,.1);box-shadow:0 5px 30px rgba(0,0,0,.1)}.wp-mail-smtp-tooltip.popover .popover-arrow{border-color:#fff}.wp-mail-smtp-tooltip[aria-hidden=true]{visibility:hidden;opacity:0;-webkit-transition:opacity .15s,visibility .15s;transition:opacity .15s,visibility .15s}.wp-mail-smtp-tooltip[aria-hidden=false]{visibility:visible;opacity:1;-webkit-transition:opacity .15s;transition:opacity .15s}.wp-mail-smtp-loader{-webkit-animation:wp-mail-smtp-loader-spin .65s linear infinite;animation:wp-mail-smtp-loader-spin .65s linear infinite}.wp-mail-smtp-loader-md{width:32px;height:32px}.wp-mail-smtp-loader-sm{width:16px;height:16px}@-webkit-keyframes wp-mail-smtp-loader-spin{0%{-webkit-transform:rotate(-270deg);transform:rotate(-270deg)}to{-webkit-transform:rotate(-630deg);transform:rotate(-630deg)}}@keyframes wp-mail-smtp-loader-spin{0%{-webkit-transform:rotate(-270deg);transform:rotate(-270deg)}to{-webkit-transform:rotate(-630deg);transform:rotate(-630deg)}}*{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}body{background:#f1f1f1;margin:0}body,body button,body input,body select,body textarea{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif}p>label{display:block}.medium-bold{font-weight:500}.medium-bold a{color:#e27730;font-weight:700}.medium-bold a:focus,.medium-bold a:hover{color:#c45e1b}.wp-mail-smtp-setup-wizard-header{text-align:center;border-top:4px solid #e27730}.wp-mail-smtp-setup-wizard-header h1{margin:0}.wp-mail-smtp-logo{display:inline-block;width:320px;margin-top:50px;padding:0 10px}.wp-mail-smtp-logo img{width:100%;height:100%}.wp-mail-smtp-setup-wizard-container{max-width:90%;width:auto;margin:0 auto}.wp-mail-smtp-setup-wizard-content{background:#fff;border:1px solid #ddd;border-radius:6px;-webkit-box-shadow:0 2px 5px rgba(0,0,0,.05);box-shadow:0 2px 5px rgba(0,0,0,.05);color:#777;font-size:16px;margin:22px 0 30px}.wp-mail-smtp-setup-wizard-content-container{padding:10px 20px}.wp-mail-smtp-setup-wizard-content .wp-mail-smtp-content-header{margin-bottom:27px}.wp-mail-smtp-setup-wizard-content h2,.wp-mail-smtp-setup-wizard-content h3{color:#222;font-size:24px;font-weight:500;margin:0 0 12px}.wp-mail-smtp-setup-wizard-content h3{font-size:16px;margin:0 0 20px}.wp-mail-smtp-setup-wizard-content .subtitle{font-size:16px;line-height:1.5;margin:0}.wp-mail-smtp-setup-wizard-content .wp-mail-smtp-separator{width:100%;border-top:1px solid #e6e6e6;clear:both;margin:20px 0}.wp-mail-smtp-setup-wizard-content .wp-mail-smtp-separator-no-margin{margin:0}.wp-mail-smtp-setup-wizard-content .wp-mail-smtp-separator-big-margin{margin:30px 0}.wp-mail-smtp-welcome .wp-mail-smtp-setup-wizard-content{text-align:center}.wp-mail-smtp-button{border-radius:3px;border:none;background-color:#f1f1f1;color:#555;cursor:pointer;display:inline-block;font-size:16px;font-weight:400;line-height:19px;padding:15px 30px;text-decoration:none}.wp-mail-smtp-button:focus,.wp-mail-smtp-button:hover{background-color:#d8d8d8}.wp-mail-smtp-button:focus{outline:none}.wp-mail-smtp-button.wp-mail-smtp-button-secondary{background-color:#2d4f60;color:#fff;font-weight:500}.wp-mail-smtp-button.wp-mail-smtp-button-secondary:focus,.wp-mail-smtp-button.wp-mail-smtp-button-secondary:hover{background-color:#1d323d}.wp-mail-smtp-button.wp-mail-smtp-button-secondary:disabled{opacity:.65;cursor:not-allowed;background-color:#2d4f60}.wp-mail-smtp-button.wp-mail-smtp-button-red{background-color:#dc3232;color:#fff;font-weight:500}.wp-mail-smtp-button.wp-mail-smtp-button-red:focus,.wp-mail-smtp-button.wp-mail-smtp-button-red:hover{background-color:#bb2020}.wp-mail-smtp-button.wp-mail-smtp-button-red:disabled{opacity:.65;cursor:not-allowed;background-color:#dc3232}.wp-mail-smtp-button.wp-mail-smtp-button-success{background-color:#6aa08b;color:#fff;font-weight:500}.wp-mail-smtp-button.wp-mail-smtp-button-success:focus,.wp-mail-smtp-button.wp-mail-smtp-button-success:hover{background-color:#548371}.wp-mail-smtp-button.wp-mail-smtp-button-success:disabled{opacity:.65;cursor:not-allowed;background-color:#6aa08b}.wp-mail-smtp-button.wp-mail-smtp-button-main{background-color:#e27730;color:#fff;font-weight:500}.wp-mail-smtp-button.wp-mail-smtp-button-main:focus,.wp-mail-smtp-button.wp-mail-smtp-button-main:hover{background-color:#c45e1b}.wp-mail-smtp-button.wp-mail-smtp-button-main:disabled{opacity:.65;cursor:not-allowed;background-color:#e27730}.wp-mail-smtp-button.wp-mail-smtp-button-small{line-height:23px;font-size:14px;padding:8px 20px}.wp-mail-smtp-button.wp-mail-smtp-button-small .wp-mail-smtp-loader-sm{margin-top:3px;margin-bottom:-3px}.wp-mail-smtp-button.wp-mail-smtp-button-large{line-height:22px;font-size:18px;padding:19px 39px}.wp-mail-smtp-button.wp-mail-smtp-button-disabled,.wp-mail-smtp-button.wp-mail-smtp-button-disabled:focus,.wp-mail-smtp-button.wp-mail-smtp-button-disabled:hover{background-color:#f3f6ff;border-color:#b7c9d9;color:#8aa4b8;font-weight:500;cursor:auto;outline:none}.wp-mail-smtp-button.wp-mail-smtp-button-activated,.wp-mail-smtp-button.wp-mail-smtp-button-activated:focus,.wp-mail-smtp-button.wp-mail-smtp-button-activated:hover{background-color:#fff;border-color:#8aa4b8;color:#8aa4b8;font-weight:500;cursor:auto;outline:none}.wp-mail-smtp-button .text-with-arrow{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.wp-mail-smtp-button .text-with-arrow-right .icon{margin-right:10px}.wp-mail-smtp-button .text-with-arrow-left .icon{margin-left:10px}.wp-mail-smtp-step-below-content{text-align:center;font-size:14px;color:#555;margin:-19px 0 47px}.wp-mail-smtp-setup-wizard-step-footer{display:block;text-align:center;min-height:110px;padding:0 20px;margin-top:30px}.wp-mail-smtp-setup-wizard-step-footer a{font-size:14px;display:block;color:#888;margin:20px 0}.wp-mail-smtp-setup-wizard-step-footer a:active,.wp-mail-smtp-setup-wizard-step-footer a:hover{color:#555;text-decoration:underline}.wp-mail-smtp-setup-wizard-step-footer-buttons{margin-bottom:20px}.wp-mail-smtp-setup-wizard-step-footer-buttons button{width:100%;margin-bottom:10px}.wp-mail-smtp-setup-wizard-step-footer-buttons button:last-child{margin-left:0;margin-bottom:0}.wp-mail-smtp-exit-link{text-align:center;margin-bottom:50px}.wp-mail-smtp-exit-link a{font-size:14px;color:#888;text-decoration:underline}.wp-mail-smtp-exit-link a:active,.wp-mail-smtp-exit-link a:hover{color:#555;text-decoration:underline}.wp-mail-smtp-setup-wizard-timeline{-webkit-box-align:center;-ms-flex-align:center;align-items:center;display:-webkit-box;display:-ms-flexbox;display:flex;margin:41px auto 0;max-width:650px;padding:0 20px}.wp-mail-smtp-setup-wizard-timeline .wp-mail-smtp-setup-wizard-timeline-step-line{background:#ddd;height:2px;margin:0 6px;width:100%}.wp-mail-smtp-setup-wizard-timeline .wp-mail-smtp-setup-wizard-timeline-step-line.wp-mail-smtp-setup-wizard-timeline-line-active{background:#6aa08b}.wp-mail-smtp-setup-wizard-timeline .wp-mail-smtp-setup-wizard-timeline-step{border:none;background-color:#999;border-radius:50%;-ms-flex-negative:0;flex-shrink:0;height:16px;width:16px}.wp-mail-smtp-setup-wizard-timeline .wp-mail-smtp-setup-wizard-timeline-step .icon{display:none}.wp-mail-smtp-setup-wizard-timeline .wp-mail-smtp-setup-wizard-timeline-step.wp-mail-smtp-setup-wizard-timeline-step-active,.wp-mail-smtp-setup-wizard-timeline .wp-mail-smtp-setup-wizard-timeline-step.wp-mail-smtp-setup-wizard-timeline-step-completed{background-color:#6aa08b;position:relative}.wp-mail-smtp-setup-wizard-timeline .wp-mail-smtp-setup-wizard-timeline-step.wp-mail-smtp-setup-wizard-timeline-step-failed{background-color:#d83638;position:relative}.wp-mail-smtp-setup-wizard-timeline .wp-mail-smtp-setup-wizard-timeline-step.wp-mail-smtp-setup-wizard-timeline-step-completed .icon-success,.wp-mail-smtp-setup-wizard-timeline .wp-mail-smtp-setup-wizard-timeline-step.wp-mail-smtp-setup-wizard-timeline-step-failed .icon-failed{color:#fff;display:block;position:absolute;right:3px;top:3px}.wp-mail-smtp-setup-wizard-timeline .wp-mail-smtp-setup-wizard-timeline-step.wp-mail-smtp-setup-wizard-timeline-step-failed .icon-failed{right:4px;top:2px}.wp-mail-smtp-input-radios-with-icons{display:block}.wp-mail-smtp-input-radios-with-icons input{opacity:0;position:absolute}.wp-mail-smtp-input-radios-with-icons label{width:100%;height:52px;color:#222;border:1px solid #ddd;background:#fff;border-radius:3px;font-size:16px;display:block;margin-bottom:20px;padding:9px;cursor:pointer}.wp-mail-smtp-input-radios-with-icons label>*{vertical-align:middle}.wp-mail-smtp-input-radios-with-icons label:hover{border:1px solid #888;-webkit-box-shadow:0 0 0 1px #888;box-shadow:0 0 0 1px #888}.wp-mail-smtp-setup-wizard-step-choose-mailer .wp-mail-smtp-setup-wizard-form-row-highlight .wp-mail-smtp-input-radios-with-icons label{border-color:#2d4f60}.wp-mail-smtp-setup-wizard-step-choose-mailer .wp-mail-smtp-setup-wizard-form-row-highlight .wp-mail-smtp-input-radios-with-icons label:hover{-webkit-box-shadow:0 0 0 1px #2d4f60;box-shadow:0 0 0 1px #2d4f60}.wp-mail-smtp-setup-wizard-step-choose-mailer .wp-mail-smtp-setup-wizard-form-row-highlight .wp-mail-smtp-input-radios-with-icons label.wp-mail-smtp-styled-radio-label-readonly:hover{-webkit-box-shadow:none;box-shadow:none}.wp-mail-smtp-input-radios-with-icons label.wp-mail-smtp-styled-radio-label-checked{border:1px solid #2d4f60;-webkit-box-shadow:0 3px 5px rgba(0,0,0,.1),0 0 0 1px #2d4f60;box-shadow:0 3px 5px rgba(0,0,0,.1),0 0 0 1px #2d4f60}.wp-mail-smtp-input-radios-with-icons label.wp-mail-smtp-styled-radio-label-readonly{color:#999;border:1px solid #ddd;-webkit-box-shadow:none;box-shadow:none;cursor:not-allowed}.wp-mail-smtp-input-radios-with-icons label.wp-mail-smtp-styled-radio-label-readonly img,.wp-mail-smtp-input-radios-with-icons label.wp-mail-smtp-styled-radio-label-readonly svg:not(.icon){opacity:.4}.wp-mail-smtp-input-radios-with-icons img{margin-right:20px}.wp-mail-smtp-input-radios-with-icons .wp-mail-smtp-styled-radio{width:32px;height:32px;position:relative;display:inline-block;border-radius:50%;background-color:#e6e6e6}.wp-mail-smtp-input-radios-with-icons .wp-mail-smtp-styled-radio .icon{display:none}.wp-mail-smtp-input-radios-with-icons .wp-mail-smtp-styled-radio.wp-mail-smtp-styled-radio-checked{background-color:#2d4f60;color:#fff}.wp-mail-smtp-input-radios-with-icons .wp-mail-smtp-styled-radio.wp-mail-smtp-styled-radio-checked .icon{display:block;position:absolute;right:8px;top:8px}.wp-mail-smtp-input-radios-with-icons .wp-mail-smtp-styled-radio-text{margin-right:10px}.wp-mail-smtp-input-radios-with-icons input:focus-visible+.wp-mail-smtp-styled-radio:not(.wp-mail-smtp-styled-radio-checked){-webkit-box-shadow:0 0 0 1px #fff,0 0 0 3px #e6e6e6;box-shadow:0 0 0 1px #fff,0 0 0 3px #e6e6e6}.wp-mail-smtp-setup-wizard-form-row-highlight{background-color:#f8f8f8;padding:20px;margin:0 -20px 20px}.wp-mail-smtp-setup-wizard-form-row-highlight .wp-mail-smtp-input-radios-with-icons label:last-child{margin-bottom:0}.wp-mail-smtp-swal.swal2-container.swal2-shown{background-color:rgba(68,68,68,.5)}.wp-mail-smtp-swal .swal2-popup{padding:10px;border-radius:0;font-size:16px;color:#555;-webkit-box-shadow:0 2px 15px rgba(0,0,0,.15);box-shadow:0 2px 15px rgba(0,0,0,.15)}.wp-mail-smtp-swal .swal2-popup .swal2-header{-webkit-box-align:normal;-ms-flex-align:normal;align-items:normal;margin:40px 40px 12px;padding:0}.wp-mail-smtp-swal .swal2-popup .swal2-header .swal2-title{font-size:24px;color:#222;margin:0;padding:0;font-weight:500;text-align:right}.wp-mail-smtp-swal .swal2-popup .swal2-header .swal2-close{color:#999;font-size:0;width:16px;height:16px;margin:10px 0 0 8px;outline:none}.wp-mail-smtp-swal .swal2-popup .swal2-header .swal2-close:before{content:"";display:inline-block;background:no-repeat url(../img/times-solid-grey.svg);width:18px;height:18px}.wp-mail-smtp-swal .swal2-popup .swal2-content{color:#555;font-size:16px;line-height:23px;padding:0 40px;margin-bottom:37px}.wp-mail-smtp-swal .swal2-popup .swal2-content #swal2-content{text-align:right;font-weight:400}.wp-mail-smtp-swal .swal2-popup .swal2-actions{border-top:1px solid #e6e6e6;margin:0 -10px;padding:30px 30px 20px;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;width:auto}@media(min-width:782px){.wp-mail-smtp-swal .swal2-popup .swal2-actions{-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}}.wp-mail-smtp-swal .swal2-popup .swal2-actions .swal2-styled:focus{-webkit-box-shadow:none;box-shadow:none}.wp-mail-smtp-swal .swal2-popup .swal2-actions .swal2-styled.swal2-cancel,.wp-mail-smtp-swal .swal2-popup .swal2-actions .swal2-styled.swal2-confirm{margin:0;display:block;width:100%}@media(min-width:782px){.wp-mail-smtp-swal .swal2-popup .swal2-actions .swal2-styled.swal2-cancel,.wp-mail-smtp-swal .swal2-popup .swal2-actions .swal2-styled.swal2-confirm{display:inline-block;width:auto}}.wp-mail-smtp-swal .swal2-popup .swal2-actions .swal2-styled.swal2-confirm{border:none;background-color:#e27730;color:#fff;border-radius:3px;font-size:16px;font-weight:500;line-height:19px;padding:15px 30px;text-decoration:none}.wp-mail-smtp-swal .swal2-popup .swal2-actions .swal2-styled.swal2-confirm:focus,.wp-mail-smtp-swal .swal2-popup .swal2-actions .swal2-styled.swal2-confirm:hover{background-color:#c45e1b}.wp-mail-smtp-swal .swal2-popup .swal2-actions .swal2-styled.swal2-confirm:after{content:"";display:inline-block;margin:0 10px -3px 0;background:no-repeat url(../img/long-arrow-alt-right-regular-white.svg);width:16px;height:18px}.wp-mail-smtp-swal .swal2-popup .swal2-actions .swal2-styled.swal2-cancel{background:none!important;border:none;padding:0!important;color:#888;font-size:14px;font-weight:400;text-decoration:underline;cursor:pointer;margin-bottom:30px}@media(min-width:782px){.wp-mail-smtp-swal .swal2-popup .swal2-actions .swal2-styled.swal2-cancel{margin-bottom:0}}.wp-mail-smtp-swal .swal2-popup .swal2-actions .swal2-styled.swal2-cancel:focus,.wp-mail-smtp-swal .swal2-popup .swal2-actions .swal2-styled.swal2-cancel:hover{color:#555}.wp-mail-smtp-swal .swal2-popup .swal2-actions .swal2-styled.swal2-cancel:before{content:"";margin:0 0 -3px 10px;display:inline-block;background:no-repeat url(../img/long-arrow-alt-left-regular-grey.svg);width:16px;height:18px}.wp-mail-smtp-swal.wp-mail-smtp-upgrade-popup .swal2-popup{border-top:7px solid #3498db;padding-top:0}.wp-mail-smtp-swal.wp-mail-smtp-upgrade-popup .swal2-popup .swal2-header{margin:10px 40px 24px;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.wp-mail-smtp-swal.wp-mail-smtp-upgrade-popup .swal2-popup .swal2-header .swal2-image{margin-top:30px;margin-bottom:17px}.wp-mail-smtp-swal.wp-mail-smtp-upgrade-popup .swal2-popup .swal2-header .swal2-title{font-weight:700;text-align:center}.wp-mail-smtp-swal.wp-mail-smtp-upgrade-popup .swal2-popup .swal2-content{margin-bottom:0}.wp-mail-smtp-swal.wp-mail-smtp-upgrade-popup .swal2-popup .swal2-content p{margin:0 auto 25px}.wp-mail-smtp-swal.wp-mail-smtp-upgrade-popup .swal2-popup .swal2-content p:last-child{margin-bottom:0}.wp-mail-smtp-swal.wp-mail-smtp-upgrade-popup .swal2-popup .swal2-content .wp-mail-smtp-button{text-transform:uppercase}.wp-mail-smtp-swal.wp-mail-smtp-upgrade-popup .swal2-popup .swal2-content #swal2-content{text-align:center}.wp-mail-smtp-swal.wp-mail-smtp-upgrade-popup .swal2-popup .swal2-content #swal2-content .wp-mail-smtp-button-main{background-color:#ff982d}.wp-mail-smtp-swal.wp-mail-smtp-upgrade-popup .swal2-popup .swal2-content #swal2-content .wp-mail-smtp-button-main:focus,.wp-mail-smtp-swal.wp-mail-smtp-upgrade-popup .swal2-popup .swal2-content #swal2-content .wp-mail-smtp-button-main:hover{background-color:#f97f00}.wp-mail-smtp-swal.wp-mail-smtp-upgrade-popup .swal2-popup .swal2-content .upgrade-bonus{position:relative;background:#faffac;margin:40px -50px 10px;padding:24px 60px 20px}.wp-mail-smtp-swal.wp-mail-smtp-upgrade-popup .swal2-popup .swal2-content .upgrade-bonus .icon-container{position:absolute;background:#2ecc71;color:#fff;width:46px;height:46px;border-radius:50%;right:calc(50% - 23px);top:-23px;border:6px solid #fff}.wp-mail-smtp-swal.wp-mail-smtp-upgrade-popup .swal2-popup .swal2-content .upgrade-bonus .icon-container .icon{position:absolute;top:10px;right:10px}.wp-mail-smtp-swal.wp-mail-smtp-upgrade-popup .swal2-popup .swal2-content .upgrade-bonus .highlight{color:#2ecc71;font-weight:500}.wp-mail-smtp-swal.wp-mail-smtp-upgrade-popup .swal2-popup .swal2-content .already-purchased{font-size:14px;color:#888}.wp-mail-smtp-swal.wp-mail-smtp-upgrade-popup .swal2-popup .swal2-content .already-purchased:focus,.wp-mail-smtp-swal.wp-mail-smtp-upgrade-popup .swal2-popup .swal2-content .already-purchased:hover{color:#555}.wp-mail-smtp-swal.wp-mail-smtp-swal-plugin-upgrade .swal2-popup .swal2-header{margin:20px}.wp-mail-smtp-swal.wp-mail-smtp-swal-plugin-upgrade .swal2-popup .swal2-content{padding:0 20px;margin-bottom:30px}.wp-mail-smtp-swal.wp-mail-smtp-swal-plugin-upgrade .swal2-popup .swal2-content .subtitle{margin:0 0 45px}.wp-mail-smtp-swal.wp-mail-smtp-swal-plugin-upgrade .swal2-popup .swal2-content .title-container{margin-bottom:7px}.wp-mail-smtp-swal.wp-mail-smtp-swal-plugin-upgrade .swal2-popup .swal2-content .bonus{padding:30px;margin:17px -30px 0;background-color:#fefcca;color:#222;border-radius:3px;text-align:center}.wp-mail-smtp-swal.wp-mail-smtp-swal-plugin-upgrade .swal2-popup .swal2-actions{-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end}.wp-mail-smtp-swal.wp-mail-smtp-swal-plugin-upgrade .swal2-popup .swal2-actions .swal2-styled.swal2-confirm{background-color:#6aa08b}.wp-mail-smtp-swal.wp-mail-smtp-swal-plugin-upgrade .swal2-popup .swal2-actions .swal2-styled.swal2-confirm:focus,.wp-mail-smtp-swal.wp-mail-smtp-swal-plugin-upgrade .swal2-popup .swal2-actions .swal2-styled.swal2-confirm:hover{background-color:#548371}.wp-mail-smtp-swal.wp-mail-smtp-swal-plugin-upgrade .swal2-popup .swal2-actions .swal2-styled.swal2-cancel:before,.wp-mail-smtp-swal.wp-mail-smtp-swal-plugin-upgrade .swal2-popup .swal2-actions .swal2-styled.swal2-confirm:after{content:none}.wp-mail-smtp-swal.wp-mail-smtp-swal-plugin-upgrade .swal2-popup .settings-input-long-checkbox .checkbox.checkbox-checked:after{top:5px}.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback-good .swal2-popup .swal2-content{margin-bottom:27px}.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback-good .swal2-popup .swal2-content img.icon{color:#fdb72c;width:16px;vertical-align:middle}.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback-good .swal2-popup .swal2-actions{border-top:none;padding:0 50px 40px}.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback-bad .swal2-popup .swal2-content{margin-bottom:16px}.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback-bad .swal2-popup .swal2-content textarea{border:1px solid #b6b6b6;color:#222;border-radius:3px;margin:27px 0 11px;padding:10px;font-size:16px;width:100%}.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback-bad .swal2-popup .swal2-content textarea:focus{outline:none;border:1px solid #2d4f60;-webkit-box-shadow:0 0 0 1px #2d4f60;box-shadow:0 0 0 1px #2d4f60}.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback-bad .swal2-popup .swal2-content .permission-container{display:-webkit-box;display:-ms-flexbox;display:flex}.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback-bad .swal2-popup .swal2-content .permission-container label{font-size:14px;margin-right:7px}.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback-bad .swal2-popup .swal2-content .permission-container input[type=checkbox]{width:16px;height:16px}.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback-bad .swal2-popup .swal2-actions{border-top:none;padding:0 50px 40px}.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback-bad .swal2-popup .swal2-actions .swal2-styled.swal2-confirm:after{content:none}.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback .swal2-popup .swal2-content{margin-bottom:47px}.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback .swal2-popup .swal2-actions{border-top:none;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;padding:0 30px 40px}.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback .swal2-popup .swal2-actions .swal2-styled.swal2-cancel,.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback .swal2-popup .swal2-actions .swal2-styled.swal2-confirm{width:128px;height:128px;padding:0;font-size:0;text-indent:-9999px;-webkit-box-shadow:none;box-shadow:none}.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback .swal2-popup .swal2-actions .swal2-styled.swal2-cancel:after,.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback .swal2-popup .swal2-actions .swal2-styled.swal2-cancel:before,.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback .swal2-popup .swal2-actions .swal2-styled.swal2-confirm:after,.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback .swal2-popup .swal2-actions .swal2-styled.swal2-confirm:before{content:none}.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback .swal2-popup .swal2-actions .swal2-styled.swal2-confirm{background:url(../img/thumbs-up.svg);margin-left:50px}.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback .swal2-popup .swal2-actions .swal2-styled.swal2-confirm:hover{background:url(../img/thumbs-up-hover.svg)}.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback .swal2-popup .swal2-actions .swal2-styled.swal2-cancel{background:url(../img/thumbs-down.svg)!important}.wp-mail-smtp-swal.wp-mail-smtp-swal-feedback .swal2-popup .swal2-actions .swal2-styled.swal2-cancel:hover{background:url(../img/thumbs-down-hover.svg)!important}.wp-mail-smtp-swal.wp-mail-smtp-swal-error .swal2-popup p{margin:0}.wp-mail-smtp-swal.wp-mail-smtp-swal-error .swal2-popup .swal2-content{padding:0 40px;margin-bottom:29px}.wp-mail-smtp-swal.wp-mail-smtp-swal-error .swal2-popup .swal2-content .subtitle{margin:0 0 26px}.wp-mail-smtp-swal.wp-mail-smtp-swal-error .swal2-popup .swal2-content .detailed-error{padding:11px 15px;font-size:14px;line-height:20px;margin:0;color:#555;border:1px solid #ddd;border-right:4px solid #dc3232;text-align:right;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.07);box-shadow:0 1px 1px rgba(0,0,0,.07)}.wp-mail-smtp-swal.wp-mail-smtp-swal-error .swal2-popup .swal2-content .detailed-error h3{font-size:14px;color:#222;font-weight:500;line-height:23px;margin:0}.wp-mail-smtp-swal.wp-mail-smtp-swal-error .swal2-popup .swal2-actions{padding:0 50px 40px;border-top:none}.wp-mail-smtp-swal.wp-mail-smtp-swal-error .swal2-popup .swal2-actions .swal2-styled.swal2-confirm:after{content:none}.wp-mail-smtp-swal.wp-mail-smtp-swal-alert .swal2-popup .swal2-header{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.wp-mail-smtp-swal.wp-mail-smtp-swal-alert .swal2-popup .swal2-content{padding:0 40px;margin-bottom:29px}.wp-mail-smtp-swal.wp-mail-smtp-swal-alert .swal2-popup .swal2-content #swal2-content{text-align:center}.wp-mail-smtp-swal.wp-mail-smtp-swal-alert .swal2-popup .swal2-content p{margin:0 0 26px}.wp-mail-smtp-swal.wp-mail-smtp-swal-alert .swal2-popup .swal2-actions{padding:0 50px 40px;border-top:none;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.wp-mail-smtp-swal.wp-mail-smtp-swal-alert .swal2-popup .swal2-actions .swal2-styled.swal2-confirm:after{content:none}.wp-mail-smtp-setup-wizard-step .license-form{color:#222}.wp-mail-smtp-setup-wizard-step .license-form input{display:block;width:100%;height:40px;font-size:16px;padding:10px;color:#222;border:1px solid #999;border-radius:3px}.wp-mail-smtp-setup-wizard-step .license-form input:focus{outline:none;border:1px solid #2d4f60;-webkit-box-shadow:0 0 0 1px #2d4f60;box-shadow:0 0 0 1px #2d4f60}.wp-mail-smtp-setup-wizard-step .license-form button{-ms-flex-negative:0;flex-shrink:0;margin-top:10px;width:100%}.wp-mail-smtp-setup-wizard-step .license-form .license-control{display:block}.wp-mail-smtp-setup-wizard-step .license-form.license-form-error input{border-color:#dc3232}.wp-mail-smtp-setup-wizard-step .license-form.license-form-error .error-message{color:#dc3232;font-size:14px;margin:5px 0 0}.wp-mail-smtp-setup-wizard-step .license-form p{margin:0 0 16px}.wp-mail-smtp-setup-wizard-step-configure-mailer .license-form p{font-size:16px;line-height:24px;color:#222}.wp-mail-smtp-setup-wizard-step-configure-mailer-settings{margin-top:29px}.wp-mail-smtp-setup-wizard-step-configure-mailer-settings.wp-mail-smtp-setup-wizard-step-configure-mailer-settings-smtp .mailer-description a{font-weight:500}.wp-mail-smtp-setup-wizard-step-configure-mailer-settings .mailer-description{font-size:16px;line-height:24px;color:#222;margin-bottom:29px}.wp-mail-smtp-setup-wizard-step-configure-mailer-settings .mailer-description-links{margin-top:0}.wp-mail-smtp-setup-wizard-step-configure-mailer-settings .mailer-description-links a{margin-left:20px}.wp-mail-smtp-setup-wizard-step-configure-mailer-settings .mailer-description-links a.wp-mail-smtp-link-docs,.wp-mail-smtp-setup-wizard-step-configure-mailer-settings .mailer-description-links a:last-child{margin-top:10px;display:block}.wp-mail-smtp-setup-wizard-step-configure-mailer-settings .mailer-description-links .wp-mail-smtp-link{font-weight:500}.wp-mail-smtp-setup-wizard-step-configure-mailer-settings .mailer-description-links .mailer-offer-link-disclosure{text-decoration:underline;text-decoration-style:dotted;font-size:14px;display:inline-block;cursor:help;margin-top:15px;color:#777}.wp-mail-smtp-setup-wizard-step-configure-mailer .wp-mail-smtp-configure-mailer-header{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.wp-mail-smtp-setup-wizard-step-configure-mailer .wp-mail-smtp-configure-mailer-header-container{width:calc(100% - 94px)}.wp-mail-smtp-setup-wizard-step-configure-mailer .wp-mail-smtp-configure-mailer-logo{width:94px;height:94px;border:1px solid #e6e6e6;border-radius:50%;position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.wp-mail-smtp-setup-wizard-step-configure-mailer .wp-mail-smtp-configure-mailer-logo svg{width:55px}.wp-mail-smtp-setup-wizard-step-configure-mailer .wp-mail-smtp-gmail-one-click-setup-switch{margin-bottom:30px}.wp-mail-smtp-setup-wizard-step-configure-mailer .wp-mail-smtp-gmail-one-click-setup-switch .label{font-size:16px}.settings-amazon-ses-identities,.settings-input-checkbox,.settings-input-long-checkbox,.settings-input-number,.settings-input-radio,.settings-input-select,.settings-input-switch,.settings-input-text,.settings-oauth-connection{margin:0 0 29px}.settings-amazon-ses-identities:last-child,.settings-input-checkbox:last-child,.settings-input-long-checkbox:last-child,.settings-input-number:last-child,.settings-input-radio:last-child,.settings-input-select:last-child,.settings-input-switch:last-child,.settings-input-text:last-child,.settings-oauth-connection:last-child{margin-bottom:20px}.settings-amazon-ses-identities .settings-input-label-container,.settings-input-checkbox .settings-input-label-container,.settings-input-long-checkbox .settings-input-label-container,.settings-input-number .settings-input-label-container,.settings-input-radio .settings-input-label-container,.settings-input-select .settings-input-label-container,.settings-input-switch .settings-input-label-container,.settings-input-text .settings-input-label-container,.settings-oauth-connection .settings-input-label-container{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin:0 0 12px}.settings-amazon-ses-identities .label,.settings-input-checkbox .label,.settings-input-long-checkbox .label,.settings-input-number .label,.settings-input-radio .label,.settings-input-select .label,.settings-input-switch .label,.settings-input-text .label,.settings-oauth-connection .label{color:#222;display:inline-block;line-height:21px;font-weight:500;font-size:18px}.settings-amazon-ses-identities .wp-mail-smtp-info,.settings-input-checkbox .wp-mail-smtp-info,.settings-input-long-checkbox .wp-mail-smtp-info,.settings-input-number .wp-mail-smtp-info,.settings-input-radio .wp-mail-smtp-info,.settings-input-select .wp-mail-smtp-info,.settings-input-switch .wp-mail-smtp-info,.settings-input-text .wp-mail-smtp-info,.settings-oauth-connection .wp-mail-smtp-info{margin-right:10px}.settings-amazon-ses-identities .error,.settings-input-checkbox .error,.settings-input-long-checkbox .error,.settings-input-number .error,.settings-input-radio .error,.settings-input-select .error,.settings-input-switch .error,.settings-input-text .error,.settings-oauth-connection .error{display:-webkit-box;display:-ms-flexbox;display:flex;color:#dc3232;font-size:14px}.settings-amazon-ses-identities .error .icon,.settings-input-checkbox .error .icon,.settings-input-long-checkbox .error .icon,.settings-input-number .error .icon,.settings-input-radio .error .icon,.settings-input-select .error .icon,.settings-input-switch .error .icon,.settings-input-text .error .icon,.settings-oauth-connection .error .icon{margin-left:10px}.settings-amazon-ses-identities.input-error input,.settings-input-checkbox.input-error input,.settings-input-long-checkbox.input-error input,.settings-input-number.input-error input,.settings-input-radio.input-error input,.settings-input-select.input-error input,.settings-input-switch.input-error input,.settings-input-text.input-error input,.settings-oauth-connection.input-error input{border-color:#dc3232}.settings-amazon-ses-identities input:disabled,.settings-input-checkbox input:disabled,.settings-input-long-checkbox input:disabled,.settings-input-number input:disabled,.settings-input-radio input:disabled,.settings-input-select input:disabled,.settings-input-switch input:disabled,.settings-input-text input:disabled,.settings-oauth-connection input:disabled{cursor:not-allowed}.settings-amazon-ses-identities .description,.settings-input-checkbox .description,.settings-input-long-checkbox .description,.settings-input-number .description,.settings-input-radio .description,.settings-input-select .description,.settings-input-switch .description,.settings-input-text .description,.settings-oauth-connection .description{font-size:14px;line-height:20px;color:#555;margin:-4px 0 0}.settings-amazon-ses-identities .description--constant,.settings-input-checkbox .description--constant,.settings-input-long-checkbox .description--constant,.settings-input-number .description--constant,.settings-input-radio .description--constant,.settings-input-select .description--constant,.settings-input-switch .description--constant,.settings-input-text .description--constant,.settings-oauth-connection .description--constant{font-size:12px;margin-top:5px}.settings-input-number input,.settings-input-text input{display:block;width:100%;height:40px;font-size:16px;padding:10px;color:#222;border:1px solid #999;border-radius:3px;margin:0 0 15px}.settings-input-number input:focus,.settings-input-text input:focus{outline:none;border:1px solid #2d4f60;-webkit-box-shadow:0 0 0 1px #2d4f60;box-shadow:0 0 0 1px #2d4f60}.settings-input-number input::-webkit-input-placeholder,.settings-input-text input::-webkit-input-placeholder{color:#888}.settings-input-number input::-moz-placeholder,.settings-input-text input::-moz-placeholder{color:#888}.settings-input-number input:-ms-input-placeholder,.settings-input-text input:-ms-input-placeholder{color:#888}.settings-input-number input::-ms-input-placeholder,.settings-input-text input::-ms-input-placeholder{color:#888}.settings-input-number input::placeholder,.settings-input-text input::placeholder{color:#888}.settings-input-number-error input,.settings-input-text-error input{border-color:#dc3232}.settings-input-number.settings-input-text-with-copy .settings-input-container,.settings-input-text.settings-input-text-with-copy .settings-input-container{display:-webkit-box;display:-ms-flexbox;display:flex;margin-bottom:15px}.settings-input-number.settings-input-text-with-copy .settings-input-container input,.settings-input-text.settings-input-text-with-copy .settings-input-container input{color:#888;margin-bottom:0}.settings-input-number.settings-input-text-with-copy .settings-input-container .wp-mail-smtp-button,.settings-input-text.settings-input-text-with-copy .settings-input-container .wp-mail-smtp-button{outline:none;margin:0 10px 0 0;background-color:#999}.settings-input-number.settings-input-text-with-copy .settings-input-container .wp-mail-smtp-button:hover,.settings-input-text.settings-input-text-with-copy .settings-input-container .wp-mail-smtp-button:hover{background-color:#888}.settings-input-number.settings-input-text-with-copy .settings-input-container .wp-mail-smtp-button-small,.settings-input-text.settings-input-text-with-copy .settings-input-container .wp-mail-smtp-button-small{padding:8px 12px}.settings-input-number.settings-input-text-with-copy .settings-input-container .wp-mail-smtp-button-copied,.settings-input-number.settings-input-text-with-copy .settings-input-container .wp-mail-smtp-button-copied:hover,.settings-input-text.settings-input-text-with-copy .settings-input-container .wp-mail-smtp-button-copied,.settings-input-text.settings-input-text-with-copy .settings-input-container .wp-mail-smtp-button-copied:hover{background-color:#6aa08b}.settings-input-number.settings-input-text-with-copy .settings-input-container .wp-mail-smtp-button .copy-button-container,.settings-input-text.settings-input-text-with-copy .settings-input-container .wp-mail-smtp-button .copy-button-container{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.settings-input-number.settings-input-text-with-copy .settings-input-container .wp-mail-smtp-button .copy-button-container .icon,.settings-input-text.settings-input-text-with-copy .settings-input-container .wp-mail-smtp-button .copy-button-container .icon{display:none}.settings-input-number.settings-input-text-with-copy .settings-input-container .wp-mail-smtp-button .copy-button-container .icon.active,.settings-input-text.settings-input-text-with-copy .settings-input-container .wp-mail-smtp-button .copy-button-container .icon.active{display:block}.settings-input-radio input{opacity:0;position:absolute}.settings-input-radio label{color:#222;font-size:14px;display:inline-block;margin:0 0 15px 30px}.settings-input-radio label:last-child{margin-left:0}.settings-input-radio label>span{vertical-align:middle}.settings-input-radio label.wp-mail-smtp-styled-radio-label-disabled{cursor:not-allowed}.settings-input-radio .wp-mail-smtp-styled-radio{width:20px;height:20px;border:1px solid #999;position:relative;display:inline-block;border-radius:50%;margin-left:10px}.settings-input-radio .wp-mail-smtp-styled-radio.wp-mail-smtp-styled-radio-checked{border-color:#2d4f60}.settings-input-radio .wp-mail-smtp-styled-radio.wp-mail-smtp-styled-radio-checked:after{right:2px;left:2px;top:2px;bottom:2px;position:absolute;content:"";background:#2d4f60;display:block;border-radius:50%}.settings-input-radio .wp-mail-smtp-styled-radio.wp-mail-smtp-styled-radio-disabled{opacity:.4}.settings-input-radio input:focus-visible+.wp-mail-smtp-styled-radio{-webkit-box-shadow:0 0 0 1px #999;box-shadow:0 0 0 1px #999}.settings-input-radio input:focus-visible+.wp-mail-smtp-styled-radio.wp-mail-smtp-styled-radio-checked{-webkit-box-shadow:0 0 0 1px #2d4f60;box-shadow:0 0 0 1px #2d4f60}.settings-input-switch.sub_setting{background-color:#f8f8f8;padding:20px;margin-top:-17px}.settings-input-switch.sub_setting .label{font-size:14px}.settings-input-switch.sub_setting .label-description{color:#555}.settings-input-switch .title{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.settings-input-switch .title .wp-mail-smtp-pro-badge{margin-right:10px;height:18px;width:auto}.settings-input-switch .control{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.settings-input-switch input{position:absolute;top:auto;overflow:hidden;clip:rect(1px,1px,1px,1px);width:1px;height:1px;white-space:nowrap}.settings-input-switch input:checked+.toggle-switch{background-color:#2d4f60}.settings-input-switch input:checked+.toggle-switch:before{-webkit-transform:translateX(-10px);-ms-transform:translateX(-10px);transform:translateX(-10px)}.settings-input-switch input:disabled:checked:hover+.toggle-switch,.settings-input-switch input:disabled:not(:checked):hover+.toggle-switch{-webkit-box-shadow:none;box-shadow:none}.settings-input-switch input:disabled:not(:checked):hover+.toggle-switch{background-color:#ddd}.settings-input-switch input:disabled+.toggle-switch{background-color:#ddd;cursor:not-allowed}.settings-input-switch input:disabled:checked+.toggle-switch{background-color:#4e88a5;cursor:not-allowed}.settings-input-switch input:checked:focus+.toggle-switch,.settings-input-switch input:checked:hover+.toggle-switch{-webkit-box-shadow:0 0 0 1px #fff,0 0 0 3px #2d4f60;box-shadow:0 0 0 1px #fff,0 0 0 3px #2d4f60}.settings-input-switch input:not(:checked):focus+.toggle-switch,.settings-input-switch input:not(:checked):hover+.toggle-switch{background-color:#999;-webkit-box-shadow:0 0 0 1px #fff,0 0 0 3px #999;box-shadow:0 0 0 1px #fff,0 0 0 3px #999}.settings-input-switch .toggle-switch{position:relative;cursor:pointer;background-color:#bbb;border-radius:10px;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out;vertical-align:middle;display:inline-block;width:30px;height:20px}.settings-input-switch .toggle-switch:before{position:absolute;content:"";height:16px;width:16px;right:2px;top:2px;background-color:#fff;border-radius:50%;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.settings-input-switch .description{margin-bottom:15px}.settings-input-switch .label-description{font-size:14px;line-height:20px;color:#222;margin:0 20px 0 0;-webkit-box-flex:1;-ms-flex:1;flex:1}.settings-input-select-container{position:relative;margin:0 0 15px}.settings-input-select-container:after{content:"";background:no-repeat url(../img/chevron-down-solid-grey.svg);left:10px;top:14px;width:12px;height:12px;position:absolute;pointer-events:none}.settings-input-select select::-ms-expand{display:none}.settings-input-select select{-webkit-appearance:none;-moz-appearance:none;appearance:none;display:block;width:100%;height:40px;font-size:16px;padding:8px 10px 8px 5px;color:#222;border:1px solid #999;border-radius:3px}.settings-input-select select:focus{outline:none;border:1px solid #2d4f60;-webkit-box-shadow:0 0 0 1px #2d4f60;box-shadow:0 0 0 1px #2d4f60}.settings-input-select select:disabled{cursor:not-allowed}.settings-input-select-error select{border-color:#dc3232}.settings-amazon-ses-identities>.wp-mail-smtp-loader{display:block}.settings-amazon-ses-identities p{margin:0 0 17px}.settings-amazon-ses-identities .description{margin-bottom:17px}.settings-amazon-ses-identities .ses-identities-container{background:#f8f8f8;padding:20px}.settings-amazon-ses-identities .ses-identities-table-container{border-radius:3px;font-size:14px;line-height:20px;text-align:right}.settings-amazon-ses-identities .ses-identities-table-container+.wp-mail-smtp-amazonses-identity-form{margin-top:20px}.settings-amazon-ses-identities .ses-identities-table-container table{width:100%;border-collapse:collapse}.settings-amazon-ses-identities .ses-identities-table-container th.ses-identity-column{color:#222;font-weight:500}.settings-amazon-ses-identities .ses-identities-table-container .ses-identity-column-sender{width:50%}.settings-amazon-ses-identities .ses-identities-table-container .ses-identity-column-status,.settings-amazon-ses-identities .ses-identities-table-container .ses-identity-column-type{width:25%}.settings-amazon-ses-identities .ses-identities-table-container tr{border-bottom:1px solid #ddd}.settings-amazon-ses-identities .ses-identities-table-container th{padding:0 0 20px}.settings-amazon-ses-identities .ses-identities-table-container td{padding:18px 0}.settings-amazon-ses-identities .ses-identities-table-container .wp-mail-smtp-button{margin-top:20px}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form{background:#f8f8f8;border-radius:3px}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form h3{font-size:14px;line-height:21px;margin-bottom:16px}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form p{font-size:14px;margin:0 0 20px}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form .settings-input-radio{margin-bottom:5px}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form .settings-input-text{margin-bottom:20px}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form .amazonses-identity-form-step .wp-mail-smtp-button-main.wp-mail-smtp-button-verify{min-width:150px}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form .amazonses-identity-form-step .ses-identities-email-success-notice{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin:0}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form .amazonses-identity-form-step .ses-identities-email-success-notice .icon{width:16px;height:16px;margin-left:10px;color:#6aa08b}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form .amazonses-identity-form-step-domain .settings-input-text{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form .amazonses-identity-form-step-domain .settings-input-text label{width:50px;margin-left:16px}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form .amazonses-identity-form-step-domain .settings-input-text label .label{font-size:16px;color:#888;font-weight:400;margin-bottom:0}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form .amazonses-identity-form-step-domain .settings-input-text .settings-input-container{width:100%}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form .amazonses-identity-form-step-domain .amazonses-dns-records{border:1px solid #ddd;border-radius:4px}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form .amazonses-identity-form-step-domain .amazonses-dns-records__row{display:-webkit-box;display:-ms-flexbox;display:flex;padding:7.5px}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form .amazonses-identity-form-step-domain .amazonses-dns-records__row--heading{border-radius:4px 4px 0 0;background-color:#eee}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form .amazonses-identity-form-step-domain .amazonses-dns-records__row--record{border-top:1px solid #ddd}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form .amazonses-identity-form-step-domain .amazonses-dns-records__col{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;-ms-flex-preferred-size:0;flex-basis:0;margin:7.5px}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form .amazonses-identity-form-step-domain .amazonses-dns-records__col--heading{font-size:14px;line-height:20px;font-weight:500;color:#444}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form .amazonses-identity-form-step-domain .amazonses-dns-records__col--record .settings-input-container{position:relative}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form .amazonses-identity-form-step-domain .amazonses-dns-records__col--record .settings-input-text{margin:0}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form .amazonses-identity-form-step-domain .amazonses-dns-records__col--record .settings-input-label-container{display:none}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form .amazonses-identity-form-step-domain .amazonses-dns-records__col--record input{margin:0;padding-left:39px}.settings-amazon-ses-identities .wp-mail-smtp-amazonses-identity-form .amazonses-identity-form-step-domain .amazonses-dns-records__col--record button{position:absolute;left:1px;top:1px;bottom:1px;padding:9px 11px;margin:0;border:none;border-radius:1px 0 0 1px}.settings-oauth-connection .description{margin-bottom:20px}.settings-oauth-connection .wp-mail-smtp-button{margin-top:-2px}.settings-oauth-connection .remove-authorization-container .description .icon{color:#6aa08b;width:16px;height:16px;margin-right:10px}.settings-oauth-connection .remove-authorization-container .description.connected-as{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.settings-oauth-connection .remove-authorization-container .wp-mail-smtp-button{margin-top:-3px}.settings-input-long-checkbox{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:30px 0;border-bottom:1px solid #e6e6e6;cursor:pointer;margin-bottom:0}.settings-input-long-checkbox.settings-input-long-checkbox-disabled{cursor:not-allowed}.settings-input-long-checkbox .title-container{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin-bottom:9px}.settings-input-long-checkbox .title-container .wp-mail-smtp-pro-badge{margin-right:10px;width:46px;height:26px}.settings-input-long-checkbox .description{margin-left:30px}.settings-input-long-checkbox .label{margin:0}.settings-input-long-checkbox input{opacity:0;position:absolute}.settings-input-long-checkbox .checkbox{width:32px;height:32px;position:relative;display:inline-block;border-radius:50%;background-color:#e6e6e6}.settings-input-long-checkbox .checkbox .icon{display:none}.settings-input-long-checkbox .checkbox.checkbox-checked{background-color:#2d4f60;color:#fff}.settings-input-long-checkbox .checkbox.checkbox-checked .icon{display:block;position:absolute;right:8px;top:8px}.settings-input-long-checkbox .checkbox.checkbox-checked.checkbox-disabled{background-color:#6aa08b}.settings-input-long-checkbox:first-child{padding-top:0;color:red}.settings-input-long-checkbox:last-child{border-bottom:none;margin-bottom:0}.settings-input-long-checkbox input:focus-visible+.checkbox{-webkit-box-shadow:0 0 0 1px #fff,0 0 0 3px #e6e6e6;box-shadow:0 0 0 1px #fff,0 0 0 3px #e6e6e6}.settings-input-long-checkbox input:focus-visible+.checkbox.checkbox-checked{-webkit-box-shadow:0 0 0 1px #fff,0 0 0 3px #2d4f60;box-shadow:0 0 0 1px #fff,0 0 0 3px #2d4f60}.settings-input-checkbox input{opacity:0;position:absolute}.settings-input-checkbox .settings-input-checkbox-container{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.settings-input-checkbox .settings-input-checkbox-container .input-label{margin-right:10px}.settings-input-checkbox .checkbox{width:24px;height:24px;position:relative;display:inline-block;border-radius:3px;border:1px solid #999;background-color:#fff}.settings-input-checkbox .checkbox .icon{display:none}.settings-input-checkbox .checkbox.checkbox-checked{background-color:#2d4f60;border:none;color:#fff}.settings-input-checkbox .checkbox.checkbox-checked .icon{display:block;position:absolute;right:5px;top:5px}.settings-input-checkbox .checkbox.checkbox-checked.checkbox-disabled{background-color:#4e88a5}.settings-input-checkbox input:focus-visible+.checkbox{-webkit-box-shadow:0 0 0 1px #999;box-shadow:0 0 0 1px #999}.settings-input-checkbox input:focus-visible+.checkbox.checkbox-checked{-webkit-box-shadow:0 0 0 1px #fff,0 0 0 3px #2d4f60;box-shadow:0 0 0 1px #fff,0 0 0 3px #2d4f60}.wp-mail-smtp-setup-wizard-step-plugin-features .wp-mail-smtp-plugin-features-header{margin-bottom:33px}.wp-mail-smtp-setup-wizard-step-plugin-features .wp-mail-smtp-plugin-features-header .wp-mail-smtp-content-header{margin-bottom:0}.wp-mail-smtp-setup-wizard-step-license .upgrade-content,.wp-mail-smtp-setup-wizard-step-license .verified-license{background-color:#e6efec;border-radius:3px;padding:30px;margin-bottom:50px;color:#222}.wp-mail-smtp-setup-wizard-step-license .upgrade-content p{margin:0 0 30px}.wp-mail-smtp-setup-wizard-step-license .verified-license{text-align:center;margin-bottom:20px}.wp-mail-smtp-setup-wizard-step-license .checked-item-list .checked-item{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;font-size:18px;margin-bottom:15px}.wp-mail-smtp-setup-wizard-step-license .checked-item-list .checked-item:last-child{margin-bottom:0}.wp-mail-smtp-setup-wizard-step-license .checked-item-list .checked-item .icon{color:#6aa08b;margin-left:15px;width:16px}.wp-mail-smtp-setup-wizard-step-license .checked-item-list .checked-item>span{width:calc(100% - 31px)}.wp-mail-smtp-setup-wizard-check-configuration .check-configuration-loading-image-container{text-align:center}.wp-mail-smtp-plugin-item{border:1px solid #ddd;border-radius:3px;padding:10px;margin-bottom:20px;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;color:#222}.wp-mail-smtp-plugin-item,.wp-mail-smtp-plugin-item-title-container{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.wp-mail-smtp-plugin-item-title-container{margin-bottom:10px}.wp-mail-smtp-plugin-item .wp-mail-smtp-button{height:32px;width:120px;text-align:center;font-size:13px;line-height:16px;font-weight:500;padding:8px 31px;color:#fff;background-color:#6693af}.wp-mail-smtp-plugin-item .wp-mail-smtp-button:hover{background-color:#2d4f60}.wp-mail-smtp-plugin-item .wp-mail-smtp-button:disabled{cursor:not-allowed;background-color:#e6e6e6;color:#777}.wp-mail-smtp-plugin-item:last-child{margin-bottom:0}.wp-mail-smtp-setup-wizard-configuration-success .plugin-item-container{margin-bottom:20px}.wp-mail-smtp-setup-wizard-configuration-success .plugin-item-container .medium-bold{color:#222;margin-bottom:20px}.wp-mail-smtp-setup-wizard-configuration-success .upgrade-banner-container{margin:30px -20px 0}.wp-mail-smtp-setup-wizard-configuration-success .upgrade-banner{padding:30px;border-radius:3px 3px 0 0;text-align:center;background-color:#ecf3f1}.wp-mail-smtp-setup-wizard-configuration-success .upgrade-banner .wp-mail-smtp-setup-wizard-content h2{margin-bottom:10px}.wp-mail-smtp-setup-wizard-configuration-success .upgrade-banner .subtitle{margin-bottom:28px}.wp-mail-smtp-setup-wizard-configuration-success .upgrade-banner .checked-item-list{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;margin-bottom:29px;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.wp-mail-smtp-setup-wizard-configuration-success .upgrade-banner .checked-item-list .checked-item{margin-bottom:10px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;font-size:18px;color:#222}.wp-mail-smtp-setup-wizard-configuration-success .upgrade-banner .checked-item-list .checked-item .icon{color:#6aa08b;margin-left:8px}.wp-mail-smtp-setup-wizard-configuration-success .bonus{margin:10px 0 0;padding:30px;background-color:#fefcca;color:#222;border-radius:0 0 3px 3px;text-align:center}.wp-mail-smtp-setup-wizard-configuration-success .wp-mail-smtp-setup-wizard-step-footer{margin:20px 0}.wp-mail-smtp-setup-wizard-configuration-success .wp-mail-smtp-setup-wizard-step-footer button{margin-bottom:10px;width:100%}.wp-mail-smtp-setup-wizard-configuration-success .wp-mail-smtp-setup-wizard-step-footer button:last-child{margin-bottom:0}.wp-mail-smtp-setup-wizard-content .wp-mail-smtp-setup-wizard-configuration-failure .wp-mail-smtp-content-header{margin-bottom:27px}.wp-mail-smtp-setup-wizard-configuration-failure .start-troubleshooting-arrow-container{margin-bottom:11px}.wp-mail-smtp-setup-wizard-configuration-failure .start-troubleshooting-arrow-container svg{width:112px;height:112px;margin:0 auto;display:block}.wp-mail-smtp-setup-wizard-configuration-failure .wp-mail-smtp-setup-wizard-step-footer{margin:20px 0}.wp-mail-smtp-setup-wizard-configuration-failure .wp-mail-smtp-setup-wizard-step-footer .wp-mail-smtp-button{margin-bottom:10px;width:100%}.wp-mail-smtp-setup-wizard-configuration-failure .wp-mail-smtp-setup-wizard-step-footer .wp-mail-smtp-button:last-child{margin-bottom:0}.wp-mail-smtp-admin-page{position:relative}.wp-mail-smtp-admin-page .wp-mail-smtp-blocked,.wp-mail-smtp-admin-page .wp-mail-smtp-loading{position:fixed;top:0;bottom:0;left:0;right:0;background:rgba(68,68,68,.5);z-index:999}.wp-mail-smtp-admin-page .wp-mail-smtp-loading{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.swal2-shown .swal2-container.swal2-backdrop-show{background:rgba(68,68,68,.5)}img{max-width:100%}a{color:#6693af}a:focus,a:hover{text-decoration:none}a .text-with-arrow{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}a .text-with-arrow-right .icon{margin-right:10px}a .text-with-arrow-left .icon{margin-left:10px}.wp-mail-smtp-notice{padding:15px;font-size:14px;line-height:20px;margin:0;color:#222;border:1px solid #ddd;border-right:4px solid #00a0d2;text-align:right;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.07);box-shadow:0 1px 1px rgba(0,0,0,.07)}.wp-mail-smtp-notice--error{border-right:4px solid #dc3232}.wp-mail-smtp-notice--info{border-right:4px solid #00a0d2}.wp-mail-smtp-notice p{margin-top:0}.wp-mail-smtp-notice p:last-child{margin-bottom:0}.wp-mail-smtp-one-click-sign-in-btn{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:0;border:none;background-color:#4285f4;border-radius:2px;-webkit-box-shadow:0 2px 4px 0 rgba(0,0,0,.25);box-shadow:0 2px 4px 0 rgba(0,0,0,.25);-webkit-transition:-webkit-box-shadow .3s ease-in-out;transition:-webkit-box-shadow .3s ease-in-out;transition:box-shadow .3s ease-in-out;transition:box-shadow .3s ease-in-out,-webkit-box-shadow .3s ease-in-out;text-decoration:none;cursor:pointer;color:#fff}.wp-mail-smtp-one-click-sign-in-btn:hover{-webkit-box-shadow:0 0 3px 3px rgba(66,133,244,.3);box-shadow:0 0 3px 3px rgba(66,133,244,.3)}.wp-mail-smtp-one-click-sign-in-btn:active{background:#3367d6}.wp-mail-smtp-one-click-sign-in-btn--disabled,.wp-mail-smtp-one-click-sign-in-btn:disabled{pointer-events:none;background-color:#d4d3d3;-webkit-box-shadow:none;box-shadow:none;color:#7f7f7f}.wp-mail-smtp-one-click-sign-in-btn--disabled .wp-mail-smtp-one-click-sign-in-icon__bg,.wp-mail-smtp-one-click-sign-in-btn--disabled .wp-mail-smtp-one-click-sign-in-icon__border,.wp-mail-smtp-one-click-sign-in-btn:disabled .wp-mail-smtp-one-click-sign-in-icon__bg,.wp-mail-smtp-one-click-sign-in-btn:disabled .wp-mail-smtp-one-click-sign-in-icon__border{fill:#d4d3d3}.wp-mail-smtp-one-click-sign-in-btn--disabled .wp-mail-smtp-one-click-sign-in-icon__symbol,.wp-mail-smtp-one-click-sign-in-btn:disabled .wp-mail-smtp-one-click-sign-in-icon__symbol{fill:#7f7f7f}.wp-mail-smtp-one-click-sign-in-btn__icon{overflow:hidden;border-radius:2px}.wp-mail-smtp-one-click-sign-in-btn__icon svg{display:block;margin:-3px}.wp-mail-smtp-one-click-sign-in-btn__text{font-size:14px;font-weight:600;margin:0 10px}@media(min-width:782px){.wp-mail-smtp-setup-wizard-container{max-width:100%;margin:0 auto;width:850px}.wp-mail-smtp-setup-wizard-content{margin:50px 0 48px}.wp-mail-smtp-setup-wizard-content .wp-mail-smtp-content-header{margin-bottom:47px}.wp-mail-smtp-setup-wizard-content-container{padding:49px 100px 30px}.wp-mail-smtp-setup-wizard-content-container-container{padding:30px 20px}.wp-mail-smtp-setup-wizard-step-plugin-features .wp-mail-smtp-setup-wizard-content-container{padding:49px 100px 19px}.wp-mail-smtp-setup-wizard-content .wp-mail-smtp-separator{margin:30px 0}.wp-mail-smtp-setup-wizard-content .wp-mail-smtp-separator-no-margin{margin:0}.wp-mail-smtp-setup-wizard-content .wp-mail-smtp-separator-big-margin{margin:50px 0}.wp-mail-smtp-setup-wizard-step .license-form .license-control{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.wp-mail-smtp-setup-wizard-step .license-form input{width:calc(100% - 195px)}.wp-mail-smtp-setup-wizard-step .license-form button{margin-top:0;width:180px;margin-right:15px}.wp-mail-smtp-welcome .wp-mail-smtp-logo{margin-top:158px;padding:0}.wp-mail-smtp-welcome .wp-mail-smtp-setup-wizard-container{width:650px}.wp-mail-smtp-welcome .wp-mail-smtp-setup-wizard-content{margin:42px 0 60px}.wp-mail-smtp-welcome .wp-mail-smtp-setup-wizard-content-container{padding:80px 65px}.wp-mail-smtp-welcome .wp-mail-smtp-setup-wizard-content-container .wp-mail-smtp-content-header{margin-bottom:36px}.wp-mail-smtp-setup-wizard-step-configure-mailer-settings{margin-top:49px}.wp-mail-smtp-setup-wizard-step-configure-mailer-settings .mailer-description{margin-bottom:49px}.wp-mail-smtp-setup-wizard-step-configure-mailer-settings .mailer-description-links{margin-top:-31px}.wp-mail-smtp-setup-wizard-step-configure-mailer-settings .mailer-description-links a.wp-mail-smtp-link-docs,.wp-mail-smtp-setup-wizard-step-configure-mailer-settings .mailer-description-links a:last-child{margin-top:0;display:inline-block}.wp-mail-smtp-setup-wizard-step-configure-mailer .wp-mail-smtp-one-click-setup-switch{margin-bottom:50px}.wp-mail-smtp-setup-wizard-check-configuration .wp-mail-smtp-setup-wizard-content-container{padding:83px 100px 66px}.wp-mail-smtp-setup-wizard-check-configuration .wp-mail-smtp-setup-wizard-content-container .wp-mail-smtp-content-header{margin-bottom:55px}.wp-mail-smtp-setup-wizard-step-plugin-features .wp-mail-smtp-plugin-features-header{margin-bottom:53px}.wp-mail-smtp-input-radios-with-icons{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-ms-flex-wrap:wrap;flex-wrap:wrap}.wp-mail-smtp-input-radios-with-icons label{width:calc(50% - 10px)}.wp-mail-smtp-setup-wizard-timeline{padding:0}.wp-mail-smtp-setup-wizard-timeline .wp-mail-smtp-setup-wizard-timeline-step-line{margin:0 10px}.wp-mail-smtp-setup-wizard-step-footer{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:0;margin-top:0}.wp-mail-smtp-setup-wizard-step-footer-buttons{margin-bottom:0;margin-left:30px}.wp-mail-smtp-setup-wizard-step-footer-buttons button{margin-bottom:0;margin-left:15px;width:inherit}.wp-mail-smtp-setup-wizard-step-footer-buttons button:last-child{margin-left:0}.wp-mail-smtp-setup-wizard-form-row-highlight{padding:20px 20px 0}.wp-mail-smtp-setup-wizard-form-row-highlight .wp-mail-smtp-input-radios-with-icons label:last-child{margin-bottom:20px}.wp-mail-smtp-setup-wizard-configuration-failure .start-troubleshooting-arrow-container svg{margin:0;display:inline-block}.wp-mail-smtp-setup-wizard-configuration-failure .wp-mail-smtp-setup-wizard-step-footer{margin:0 30px}.wp-mail-smtp-setup-wizard-configuration-failure .wp-mail-smtp-setup-wizard-step-footer .wp-mail-smtp-button{margin-bottom:0;-webkit-box-flex:10;-ms-flex:10;flex:10}.wp-mail-smtp-setup-wizard-configuration-failure .wp-mail-smtp-setup-wizard-step-footer .wp-mail-smtp-button.wp-mail-smtp-button-main{-webkit-box-flex:11;-ms-flex:11;flex:11;margin-left:30px}.wp-mail-smtp-setup-wizard-configuration-success .upgrade-banner-container{margin:50px -70px 0}.wp-mail-smtp-setup-wizard-configuration-success .upgrade-banner .checked-item-list{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;text-align:center}.wp-mail-smtp-setup-wizard-configuration-success .upgrade-banner .checked-item-list .checked-item{margin-bottom:0}.wp-mail-smtp-setup-wizard-configuration-success .wp-mail-smtp-setup-wizard-step-footer{margin:0 30px;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.wp-mail-smtp-setup-wizard-configuration-success .wp-mail-smtp-setup-wizard-step-footer button{-webkit-box-flex:10;-ms-flex:10;flex:10;margin-bottom:0;margin-left:30px}.wp-mail-smtp-setup-wizard-configuration-success .wp-mail-smtp-setup-wizard-step-footer button:last-child{margin-left:0}.wp-mail-smtp-setup-wizard-configuration-success .wp-mail-smtp-setup-wizard-step-footer button.wp-mail-smtp-button-main{-webkit-box-flex:11;-ms-flex:11;flex:11}.wp-mail-smtp-plugin-item{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.wp-mail-smtp-plugin-item-title-container{margin-bottom:0}.wp-mail-smtp-swal.wp-mail-smtp-swal-plugin-upgrade .swal2-popup .swal2-header{margin:75px 90px 18px}.wp-mail-smtp-swal.wp-mail-smtp-swal-plugin-upgrade .swal2-popup .swal2-content{padding:0 90px}.wp-mail-smtp-swal.wp-mail-smtp-swal-plugin-upgrade .swal2-popup .swal2-content .bonus{margin:17px -70px 0}.wp-mail-smtp-swal.wp-mail-smtp-swal-plugin-upgrade .swal2-popup .swal2-actions .swal2-styled.swal2-confirm{margin-right:30px}.wp-mail-smtp-setup-wizard-step-footer a{margin:0 30px 0 0}a .text-with-arrow{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}}.wp-mail-smtp-pro-badge[data-v-2d9202de]{float:left;margin-top:3px;width:46px;height:26px}.wp-mail-smtp-logo-icon[data-v-2d9202de]{width:32px;height:32px}.wp-mail-smtp-setup-wizard-step-count[data-v-44fd4a93]{margin:0 0 16px;font-size:14px;line-height:18px;color:#b6b6b6}.wp-mail-smtp-notice[data-v-099efe34]{margin-top:-20px;margin-bottom:30px}.wp-mail-smtp-info .icon[data-v-74a4d2ae]{color:#ccc}.wp-mail-smtp-logo-icon[data-v-2e2edfa6]{width:32px;height:32px;margin-left:10px}.wp-mail-smtp-notice[data-v-05d90eba],.wp-mail-smtp-notice[data-v-a87376ac]{margin-top:-23px;margin-bottom:20px}
\ No newline at end of file
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/amazonses.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/amazonses.svg
new file mode 100755
index 00000000..3ac47762
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/amazonses.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/arrow.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/arrow.svg
new file mode 100755
index 00000000..13c1b3b9
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/arrow.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/brevo.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/brevo.svg
new file mode 100755
index 00000000..2b35cb71
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/brevo.svg
@@ -0,0 +1,4 @@
+
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/check-circle-solid-white.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/check-circle-solid-white.svg
new file mode 100755
index 00000000..02f7e477
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/check-circle-solid-white.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/check-circle-solid.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/check-circle-solid.svg
new file mode 100755
index 00000000..6aaa9742
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/check-circle-solid.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/check-solid.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/check-solid.svg
new file mode 100755
index 00000000..15d7ab5e
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/check-solid.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/chevron-down-solid-grey.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/chevron-down-solid-grey.svg
new file mode 100755
index 00000000..583c8ee4
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/chevron-down-solid-grey.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/copy-solid.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/copy-solid.svg
new file mode 100755
index 00000000..51fcb5b2
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/copy-solid.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/elasticemail.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/elasticemail.svg
new file mode 100755
index 00000000..16db4db8
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/elasticemail.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/exclamation-circle-solid.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/exclamation-circle-solid.svg
new file mode 100755
index 00000000..27647c3b
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/exclamation-circle-solid.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/gmail-sign-in-btn.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/gmail-sign-in-btn.svg
new file mode 100755
index 00000000..70d86126
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/gmail-sign-in-btn.svg
@@ -0,0 +1 @@
+
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/gmail.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/gmail.svg
new file mode 100755
index 00000000..2472a43c
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/gmail.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/info-circle-solid.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/info-circle-solid.svg
new file mode 100755
index 00000000..9e86172e
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/info-circle-solid.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/loading-blue.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/loading-blue.svg
new file mode 100755
index 00000000..5519045f
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/loading-blue.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/loading-pattie.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/loading-pattie.svg
new file mode 100755
index 00000000..ffe6a685
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/loading-pattie.svg
@@ -0,0 +1,28 @@
+
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/loading-white.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/loading-white.svg
new file mode 100755
index 00000000..ae6fe144
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/loading-white.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/loading.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/loading.svg
new file mode 100755
index 00000000..0be46bd5
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/loading.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/lock-solid.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/lock-solid.svg
new file mode 100755
index 00000000..af7bed5a
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/lock-solid.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/logo.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/logo.svg
new file mode 100755
index 00000000..8ac53862
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/logo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/long-arrow-alt-left-regular-grey.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/long-arrow-alt-left-regular-grey.svg
new file mode 100755
index 00000000..97904975
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/long-arrow-alt-left-regular-grey.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/long-arrow-alt-left-regular.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/long-arrow-alt-left-regular.svg
new file mode 100755
index 00000000..0055aa1b
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/long-arrow-alt-left-regular.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/long-arrow-alt-right-regular-white.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/long-arrow-alt-right-regular-white.svg
new file mode 100755
index 00000000..87ce9f17
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/long-arrow-alt-right-regular-white.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/long-arrow-alt-right-regular.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/long-arrow-alt-right-regular.svg
new file mode 100755
index 00000000..45841124
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/long-arrow-alt-right-regular.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/mailersend.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/mailersend.svg
new file mode 100755
index 00000000..8f292d56
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/mailersend.svg
@@ -0,0 +1,10 @@
+
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/mailgun.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/mailgun.svg
new file mode 100755
index 00000000..a1061808
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/mailgun.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/mailjet.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/mailjet.svg
new file mode 100755
index 00000000..559af28e
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/mailjet.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/mandrill.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/mandrill.svg
new file mode 100755
index 00000000..ef7a4e67
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/mandrill.svg
@@ -0,0 +1,15 @@
+
+
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/outlook-sign-in-btn.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/outlook-sign-in-btn.svg
new file mode 100755
index 00000000..81f0c43c
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/outlook-sign-in-btn.svg
@@ -0,0 +1 @@
+
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/outlook.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/outlook.svg
new file mode 100755
index 00000000..22fbc0c1
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/outlook.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/postmark.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/postmark.svg
new file mode 100755
index 00000000..e32dffe1
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/postmark.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/pro-badge.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/pro-badge.svg
new file mode 100755
index 00000000..fa9e4e14
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/pro-badge.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/question-circle-solid.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/question-circle-solid.svg
new file mode 100755
index 00000000..a7c51850
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/question-circle-solid.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/resend.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/resend.svg
new file mode 100755
index 00000000..cc696be3
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/resend.svg
@@ -0,0 +1 @@
+
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/sendgrid.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/sendgrid.svg
new file mode 100755
index 00000000..27f77d33
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/sendgrid.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/sendlayer.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/sendlayer.svg
new file mode 100755
index 00000000..25f0d650
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/sendlayer.svg
@@ -0,0 +1,5 @@
+
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/smtp.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/smtp.svg
new file mode 100755
index 00000000..02eb1c6f
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/smtp.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/smtp2go.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/smtp2go.svg
new file mode 100755
index 00000000..9f2a4933
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/smtp2go.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/smtpcom.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/smtpcom.svg
new file mode 100755
index 00000000..616fb47c
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/smtpcom.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/sparkpost.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/sparkpost.svg
new file mode 100755
index 00000000..41300315
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/sparkpost.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/star-solid.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/star-solid.svg
new file mode 100755
index 00000000..70cab3ef
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/star-solid.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/thumbs-down-hover.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/thumbs-down-hover.svg
new file mode 100755
index 00000000..4226b121
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/thumbs-down-hover.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/thumbs-down.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/thumbs-down.svg
new file mode 100755
index 00000000..2ccf0406
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/thumbs-down.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/thumbs-up-hover.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/thumbs-up-hover.svg
new file mode 100755
index 00000000..6a9876b3
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/thumbs-up-hover.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/thumbs-up.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/thumbs-up.svg
new file mode 100755
index 00000000..9f9deaff
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/thumbs-up.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/times-solid-grey.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/times-solid-grey.svg
new file mode 100755
index 00000000..47b4d985
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/times-solid-grey.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/times-solid.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/times-solid.svg
new file mode 100755
index 00000000..81446224
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/times-solid.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/working.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/working.svg
new file mode 100755
index 00000000..cadb5865
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/working.svg
@@ -0,0 +1,67 @@
+
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/img/zoho.svg b/wp-content/plugins/wp-mail-smtp/assets/vue/img/zoho.svg
new file mode 100755
index 00000000..36de119f
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/img/zoho.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/wp-content/plugins/wp-mail-smtp/assets/vue/js/chunk-vendors.min.js b/wp-content/plugins/wp-mail-smtp/assets/vue/js/chunk-vendors.min.js
new file mode 100755
index 00000000..2ac855ca
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/assets/vue/js/chunk-vendors.min.js
@@ -0,0 +1,43 @@
+(self["wpmailsmtpjsonp"]=self["wpmailsmtpjsonp"]||[]).push([[504],{1656:function(t,e,n){"use strict";function r(t,e,n,r,o,i,a,s){var c,u="function"===typeof t?t.options:t;if(e&&(u.render=e,u.staticRenderFns=n,u._compiled=!0),r&&(u.functional=!0),i&&(u._scopeId="data-v-"+i),a?(c=function(t){t=t||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext,t||"undefined"===typeof __VUE_SSR_CONTEXT__||(t=__VUE_SSR_CONTEXT__),o&&o.call(this,t),t&&t._registeredComponents&&t._registeredComponents.add(a)},u._ssrRegister=c):o&&(c=s?function(){o.call(this,(u.functional?this.parent:this).$root.$options.shadowRoot)}:o),c)if(u.functional){u._injectStyles=c;var l=u.render;u.render=function(t,e){return c.call(e),l(t,e)}}else{var f=u.beforeCreate;u.beforeCreate=f?[].concat(f,c):[c]}return{exports:t,options:u}}n.d(e,{A:function(){return r}})},7953:function(t,e,n){"use strict";n.d(e,{__:function(){return ft},fh:function(){return lt},nv:function(){return u}});var r,o,i,a,s=/%(((\d+)\$)|(\(([$_a-zA-Z][$_a-zA-Z0-9]*)\)))?[ +0#-]*\d*(\.(\d+|\*))?(ll|[lhqL])?([cduxXefgsp%])/g;function c(t,...e){var n=0;return Array.isArray(e[0])&&(e=e[0]),t.replace(s,(function(){var t,r,o,i,a;return t=arguments[3],r=arguments[5],o=arguments[7],i=arguments[9],"%"===i?"%":("*"===o&&(o=e[n],n++),void 0===r?(void 0===t&&(t=n+1),n++,a=e[t-1]):e[0]&&"object"===typeof e[0]&&e[0].hasOwnProperty(r)&&(a=e[0][r]),"f"===i?a=parseFloat(a)||0:"d"===i&&(a=parseInt(a)||0),void 0!==o&&("f"===i?a=a.toFixed(o):"s"===i&&(a=a.substr(0,o))),void 0!==a&&null!==a?a:"")}))}function u(t,...e){return c(t,...e)}function l(t){var e,n,s,c,u=[],l=[];while(e=t.match(a)){n=e[0],s=t.substr(0,e.index).trim(),s&&u.push(s);while(c=l.pop()){if(i[n]){if(i[n][0]===c){n=i[n][1]||n;break}}else if(o.indexOf(c)>=0||r[c]":5,">=":5,"==":4,"!=":4,"&&":3,"||":2,"?":1,"?:":1},o=["(","?"],i={")":["("],":":["?","?:"]},a=/<=|>=|==|!=|&&|\|\||\?:|\(|!|\*|\/|%|\+|-|<|>|\?|\)|:/;var f={"!":function(t){return!t},"*":function(t,e){return t*e},"/":function(t,e){return t/e},"%":function(t,e){return t%e},"+":function(t,e){return t+e},"-":function(t,e){return t-e},"<":function(t,e){return t":function(t,e){return t>e},">=":function(t,e){return t>=e},"==":function(t,e){return t===e},"!=":function(t,e){return t!==e},"&&":function(t,e){return t&&e},"||":function(t,e){return t||e},"?:":function(t,e,n){if(t)throw e;return n}};function p(t,e){var n,r,o,i,a,s,c=[];for(n=0;n{const r=new g({}),o=new Set,i=()=>{o.forEach((t=>t()))},a=t=>(o.add(t),()=>o.delete(t)),s=(t="default")=>r.data[t],c=(t,e="default")=>{r.data[e]={...r.data[e],...t},r.data[e][""]={...y[""],...r.data[e]?.[""]},delete r.pluralForms[e]},u=(t,e)=>{c(t,e),i()},l=(t,e="default")=>{r.data[e]={...r.data[e],...t,"":{...y[""],...r.data[e]?.[""],...t?.[""]}},delete r.pluralForms[e],i()},f=(t,e)=>{r.data={},r.pluralForms={},u(t,e)},p=(t="default",e,n,o,i)=>(r.data[t]||c(void 0,t),r.dcnpgettext(t,e,n,o,i)),d=t=>t||"default",h=(t,e)=>{let r=p(e,void 0,t);return n?(r=n.applyFilters("i18n.gettext",r,t,e),n.applyFilters("i18n.gettext_"+d(e),r,t,e)):r},v=(t,e,r)=>{let o=p(r,e,t);return n?(o=n.applyFilters("i18n.gettext_with_context",o,t,e,r),n.applyFilters("i18n.gettext_with_context_"+d(r),o,t,e,r)):o},m=(t,e,r,o)=>{let i=p(o,void 0,t,e,r);return n?(i=n.applyFilters("i18n.ngettext",i,t,e,r,o),n.applyFilters("i18n.ngettext_"+d(o),i,t,e,r,o)):i},b=(t,e,r,o,i)=>{let a=p(i,o,t,e,r);return n?(a=n.applyFilters("i18n.ngettext_with_context",a,t,e,r,o,i),n.applyFilters("i18n.ngettext_with_context_"+d(i),a,t,e,r,o,i)):a},_=()=>"rtl"===v("ltr","text direction"),x=(t,e,o)=>{const i=e?e+""+t:t;let a=!!r.data?.[o??"default"]?.[i];return n&&(a=n.applyFilters("i18n.has_translation",a,t,e,o),a=n.applyFilters("i18n.has_translation_"+d(o),a,t,e,o)),a};if(t&&u(t,e),n){const t=t=>{w.test(t)&&i()};n.addAction("hookAdded","core/i18n",t),n.addAction("hookRemoved","core/i18n",t)}return{getLocaleData:s,setLocaleData:u,addLocaleData:l,resetLocaleData:f,subscribe:a,__:h,_x:v,_n:m,_nx:b,isRTL:_,hasTranslation:x}};function _(t){return"string"!==typeof t||""===t?(console.error("The namespace must be a non-empty string."),!1):!!/^[a-zA-Z][a-zA-Z0-9_.\-\/]*$/.test(t)||(console.error("The namespace can only contain numbers, letters, dashes, periods, underscores and slashes."),!1)}var x=_;function O(t){return"string"!==typeof t||""===t?(console.error("The hook name must be a non-empty string."),!1):/^__/.test(t)?(console.error("The hook name cannot begin with `__`."),!1):!!/^[a-zA-Z][a-zA-Z0-9_.-]*$/.test(t)||(console.error("The hook name can only contain numbers, letters, dashes, periods and underscores."),!1)}var C=O;function k(t,e){return function(n,r,o,i=10){const a=t[e];if(!C(n))return;if(!x(r))return;if("function"!==typeof o)return void console.error("The hook callback must be a function.");if("number"!==typeof i)return void console.error("If specified, the hook priority must be a number.");const s={callback:o,priority:i,namespace:r};if(a[n]){const t=a[n].handlers;let e;for(e=t.length;e>0;e--)if(i>=t[e-1].priority)break;e===t.length?t[e]=s:t.splice(e,0,s),a.__current.forEach((t=>{t.name===n&&t.currentIndex>=e&&t.currentIndex++}))}else a[n]={handlers:[s],runs:0};"hookAdded"!==n&&t.doAction("hookAdded",n,r,o,i)}}var E=k;function j(t,e,n=!1){return function(r,o){const i=t[e];if(!C(r))return;if(!n&&!x(o))return;if(!i[r])return 0;let a=0;if(n)a=i[r].handlers.length,i[r]={runs:i[r].runs,handlers:[]};else{const t=i[r].handlers;for(let e=t.length-1;e>=0;e--)t[e].namespace===o&&(t.splice(e,1),a++,i.__current.forEach((t=>{t.name===r&&t.currentIndex>=e&&t.currentIndex--})))}return"hookRemoved"!==r&&t.doAction("hookRemoved",r,o),a}}var S=j;function A(t,e){return function(n,r){const o=t[e];return"undefined"!==typeof r?n in o&&o[n].handlers.some((t=>t.namespace===r)):n in o}}var T=A;function $(t,e,n,r){return function(o,...i){const a=t[e];a[o]||(a[o]={handlers:[],runs:0}),a[o].runs++;const s=a[o].handlers;if(!s||!s.length)return n?i[0]:void 0;const c={name:o,currentIndex:0};async function u(){try{a.__current.add(c);let t=n?i[0]:void 0;while(c.currentIndex0:Array.from(r.__current).some((t=>t.name===n))}}var I=N;function F(t,e){return function(n){const r=t[e];if(C(n))return r[n]&&r[n].runs?r[n].runs:0}}var D=F;class B{actions;filters;addAction;addFilter;removeAction;removeFilter;hasAction;hasFilter;removeAllActions;removeAllFilters;doAction;doActionAsync;applyFilters;applyFiltersAsync;currentAction;currentFilter;doingAction;doingFilter;didAction;didFilter;constructor(){this.actions=Object.create(null),this.actions.__current=new Set,this.filters=Object.create(null),this.filters.__current=new Set,this.addAction=E(this,"actions"),this.addFilter=E(this,"filters"),this.removeAction=S(this,"actions"),this.removeFilter=S(this,"filters"),this.hasAction=T(this,"actions"),this.hasFilter=T(this,"filters"),this.removeAllActions=S(this,"actions",!0),this.removeAllFilters=S(this,"filters",!0),this.doAction=P(this,"actions",!1,!1),this.doActionAsync=P(this,"actions",!1,!0),this.applyFilters=P(this,"filters",!0,!1),this.applyFiltersAsync=P(this,"filters",!0,!0),this.currentAction=R(this,"actions"),this.currentFilter=R(this,"filters"),this.doingAction=I(this,"actions"),this.doingFilter=I(this,"filters"),this.didAction=D(this,"actions"),this.didFilter=D(this,"filters")}}function M(){return new B}var z=M;const U=z(),{addAction:H,addFilter:q,removeAction:V,removeFilter:W,hasAction:K,hasFilter:G,removeAllActions:Y,removeAllFilters:X,doAction:J,doActionAsync:Z,applyFilters:Q,applyFiltersAsync:tt,currentAction:et,currentFilter:nt,doingAction:rt,doingFilter:ot,didAction:it,didFilter:at,actions:st,filters:ct}=U,ut=b(void 0,void 0,U);ut.getLocaleData.bind(ut);const lt=ut.setLocaleData.bind(ut),ft=(ut.resetLocaleData.bind(ut),ut.subscribe.bind(ut),ut.__.bind(ut));ut._x.bind(ut),ut._n.bind(ut),ut._nx.bind(ut),ut.isRTL.bind(ut),ut.hasTranslation.bind(ut)},7193:function(t,e,n){t=n.nmd(t);var r=200,o="__lodash_hash_undefined__",i=9007199254740991,a="[object Arguments]",s="[object Array]",c="[object Boolean]",u="[object Date]",l="[object Error]",f="[object Function]",p="[object GeneratorFunction]",d="[object Map]",h="[object Number]",v="[object Object]",m="[object Promise]",g="[object RegExp]",y="[object Set]",w="[object String]",b="[object Symbol]",_="[object WeakMap]",x="[object ArrayBuffer]",O="[object DataView]",C="[object Float32Array]",k="[object Float64Array]",E="[object Int8Array]",j="[object Int16Array]",S="[object Int32Array]",A="[object Uint8Array]",T="[object Uint8ClampedArray]",$="[object Uint16Array]",P="[object Uint32Array]",L=/[\\^$.*+?()[\]{}|]/g,R=/\w*$/,N=/^\[object .+?Constructor\]$/,I=/^(?:0|[1-9]\d*)$/,F={};F[a]=F[s]=F[x]=F[O]=F[c]=F[u]=F[C]=F[k]=F[E]=F[j]=F[S]=F[d]=F[h]=F[v]=F[g]=F[y]=F[w]=F[b]=F[A]=F[T]=F[$]=F[P]=!0,F[l]=F[f]=F[_]=!1;var D="object"==typeof n.g&&n.g&&n.g.Object===Object&&n.g,B="object"==typeof self&&self&&self.Object===Object&&self,M=D||B||Function("return this")(),z=e&&!e.nodeType&&e,U=z&&t&&!t.nodeType&&t,H=U&&U.exports===z;function q(t,e){return t.set(e[0],e[1]),t}function V(t,e){return t.add(e),t}function W(t,e){var n=-1,r=t?t.length:0;while(++n-1}function qt(t,e){var n=this.__data__,r=ie(n,t);return r<0?n.push([t,e]):n[r][1]=e,this}function Vt(t){var e=-1,n=t?t.length:0;this.clear();while(++e-1&&t%1==0&&t-1&&t%1==0&&t<=i}function We(t){var e=typeof t;return!!t&&("object"==e||"function"==e)}function Ke(t){return!!t&&"object"==typeof t}function Ge(t){return ze(t)?re(t):pe(t)}function Ye(){return[]}function Xe(){return!1}t.exports=Fe},181:function(t,e,n){var r="Expected a function",o=NaN,i="[object Symbol]",a=/^\s+|\s+$/g,s=/^[-+]0x[0-9a-f]+$/i,c=/^0b[01]+$/i,u=/^0o[0-7]+$/i,l=parseInt,f="object"==typeof n.g&&n.g&&n.g.Object===Object&&n.g,p="object"==typeof self&&self&&self.Object===Object&&self,d=f||p||Function("return this")(),h=Object.prototype,v=h.toString,m=Math.max,g=Math.min,y=function(){return d.Date.now()};function w(t,e,n){var o,i,a,s,c,u,l=0,f=!1,p=!1,d=!0;if("function"!=typeof t)throw new TypeError(r);function h(e){var n=o,r=i;return o=i=void 0,l=e,s=t.apply(r,n),s}function v(t){return l=t,c=setTimeout(x,e),f?h(t):s}function w(t){var n=t-u,r=t-l,o=e-n;return p?g(o,a-r):o}function _(t){var n=t-u,r=t-l;return void 0===u||n>=e||n<0||p&&r>=a}function x(){var t=y();if(_(t))return C(t);c=setTimeout(x,w(t))}function C(t){return c=void 0,d&&o?h(t):(o=i=void 0,s)}function k(){void 0!==c&&clearTimeout(c),l=0,o=u=i=c=void 0}function E(){return void 0===c?s:C(y())}function j(){var t=y(),n=_(t);if(o=arguments,i=this,u=t,n){if(void 0===c)return v(u);if(p)return c=setTimeout(x,e),h(u)}return void 0===c&&(c=setTimeout(x,e)),s}return e=O(e)||0,b(n)&&(f=!!n.leading,p="maxWait"in n,a=p?m(O(n.maxWait)||0,e):a,d="trailing"in n?!!n.trailing:d),j.cancel=k,j.flush=E,j}function b(t){var e=typeof t;return!!t&&("object"==e||"function"==e)}function _(t){return!!t&&"object"==typeof t}function x(t){return"symbol"==typeof t||_(t)&&v.call(t)==i}function O(t){if("number"==typeof t)return t;if(x(t))return o;if(b(t)){var e="function"==typeof t.valueOf?t.valueOf():t;t=b(e)?e+"":e}if("string"!=typeof t)return 0===t?t:+t;t=t.replace(a,"");var n=c.test(t);return n||u.test(t)?l(t.slice(2),n?2:8):s.test(t)?o:+t}t.exports=w},470:function(t,e,n){var r="Expected a function",o="__lodash_hash_undefined__",i=1/0,a=9007199254740991,s="[object Arguments]",c="[object Function]",u="[object GeneratorFunction]",l="[object Symbol]",f=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,p=/^\w*$/,d=/^\./,h=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,v=/[\\^$.*+?()[\]{}|]/g,m=/\\(\\)?/g,g=/^\[object .+?Constructor\]$/,y=/^(?:0|[1-9]\d*)$/,w="object"==typeof n.g&&n.g&&n.g.Object===Object&&n.g,b="object"==typeof self&&self&&self.Object===Object&&self,_=w||b||Function("return this")();function x(t,e){return null==t?void 0:t[e]}function O(t){var e=!1;if(null!=t&&"function"!=typeof t.toString)try{e=!!(t+"")}catch(n){}return e}var C=Array.prototype,k=Function.prototype,E=Object.prototype,j=_["__core-js_shared__"],S=function(){var t=/[^.]+$/.exec(j&&j.keys&&j.keys.IE_PROTO||"");return t?"Symbol(src)_1."+t:""}(),A=k.toString,T=E.hasOwnProperty,$=E.toString,P=RegExp("^"+A.call(T).replace(v,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),L=_.Symbol,R=E.propertyIsEnumerable,N=C.splice,I=lt(_,"Map"),F=lt(Object,"create"),D=L?L.prototype:void 0,B=D?D.toString:void 0;function M(t){var e=-1,n=t?t.length:0;this.clear();while(++e-1}function J(t,e){var n=this.__data__,r=ot(n,t);return r<0?n.push([t,e]):n[r][1]=e,this}function Z(t){var e=-1,n=t?t.length:0;this.clear();while(++e-1&&t%1==0&&t-1&&t%1==0&&t<=a}function jt(t){var e=typeof t;return!!t&&("object"==e||"function"==e)}function St(t){return!!t&&"object"==typeof t}function At(t){return"symbol"==typeof t||St(t)&&$.call(t)==l}function Tt(t){return null==t?"":st(t)}function $t(t,e){return null!=t&&ft(t,e,it)}t.exports=$t},182:function(t,e,n){t=n.nmd(t);var r=200,o="__lodash_hash_undefined__",i=800,a=16,s=9007199254740991,c="[object Arguments]",u="[object Array]",l="[object AsyncFunction]",f="[object Boolean]",p="[object Date]",d="[object Error]",h="[object Function]",v="[object GeneratorFunction]",m="[object Map]",g="[object Number]",y="[object Null]",w="[object Object]",b="[object Proxy]",_="[object RegExp]",x="[object Set]",O="[object String]",C="[object Undefined]",k="[object WeakMap]",E="[object ArrayBuffer]",j="[object DataView]",S="[object Float32Array]",A="[object Float64Array]",T="[object Int8Array]",$="[object Int16Array]",P="[object Int32Array]",L="[object Uint8Array]",R="[object Uint8ClampedArray]",N="[object Uint16Array]",I="[object Uint32Array]",F=/[\\^$.*+?()[\]{}|]/g,D=/^\[object .+?Constructor\]$/,B=/^(?:0|[1-9]\d*)$/,M={};M[S]=M[A]=M[T]=M[$]=M[P]=M[L]=M[R]=M[N]=M[I]=!0,M[c]=M[u]=M[E]=M[f]=M[j]=M[p]=M[d]=M[h]=M[m]=M[g]=M[w]=M[_]=M[x]=M[O]=M[k]=!1;var z="object"==typeof n.g&&n.g&&n.g.Object===Object&&n.g,U="object"==typeof self&&self&&self.Object===Object&&self,H=z||U||Function("return this")(),q=e&&!e.nodeType&&e,V=q&&t&&!t.nodeType&&t,W=V&&V.exports===q,K=W&&z.process,G=function(){try{var t=V&&V.require&&V.require("util").types;return t||K&&K.binding&&K.binding("util")}catch(e){}}(),Y=G&&G.isTypedArray;function X(t,e,n){switch(n.length){case 0:return t.call(e);case 1:return t.call(e,n[0]);case 2:return t.call(e,n[0],n[1]);case 3:return t.call(e,n[0],n[1],n[2])}return t.apply(e,n)}function J(t,e){var n=-1,r=Array(t);while(++n-1}function Dt(t,e){var n=this.__data__,r=te(n,t);return r<0?(++this.size,n.push([t,e])):n[r][1]=e,this}function Bt(t){var e=-1,n=null==t?0:t.length;this.clear();while(++e1?n[o-1]:void 0,a=o>2?n[2]:void 0;i=t.length>3&&"function"==typeof i?(o--,i):void 0,a&&Ce(n[0],n[1],a)&&(i=o<3?void 0:i,o=1),e=Object(e);while(++r-1&&t%1==0&&t0){if(++e>=i)return arguments[0]}else e=0;return t.apply(void 0,arguments)}}function Re(t){if(null!=t){try{return it.call(t)}catch(e){}try{return t+""}catch(e){}}return""}function Ne(t,e){return t===e||t!==t&&e!==e}var Ie=oe(function(){return arguments}())?oe:function(t){return qe(t)&&at.call(t,"callee")&&!gt.call(t,"callee")},Fe=Array.isArray;function De(t){return null!=t&&Ue(t.length)&&!ze(t)}function Be(t){return qe(t)&&De(t)}var Me=_t||Ze;function ze(t){if(!He(t))return!1;var e=re(t);return e==h||e==v||e==l||e==b}function Ue(t){return"number"==typeof t&&t>-1&&t%1==0&&t<=s}function He(t){var e=typeof t;return null!=t&&("object"==e||"function"==e)}function qe(t){return null!=t&&"object"==typeof t}function Ve(t){if(!qe(t)||re(t)!=w)return!1;var e=vt(t);if(null===e)return!0;var n=at.call(e,"constructor")&&e.constructor;return"function"==typeof n&&n instanceof n&&it.call(n)==ut}var We=Y?Z(Y):ae;function Ke(t){return me(t,Ge(t))}function Ge(t){return De(t)?Jt(t,!0):se(t)}var Ye=ge((function(t,e,n){ce(t,e,n)}));function Xe(t){return function(){return t}}function Je(t){return t}function Ze(){return!1}t.exports=Ye},5580:function(t,e,n){var r=n(6110),o=n(9325),i=r(o,"DataView");t.exports=i},1549:function(t,e,n){var r=n(9651),o=n(3862),i=n(6721),a=n(2749),s=n(5749);function c(t){var e=-1,n=null==t?0:t.length;this.clear();while(++e1?n[i-1]:void 0,s=i>2?n[2]:void 0;a=t.length>3&&"function"==typeof a?(i--,a):void 0,s&&o(n[0],n[1],s)&&(a=i<3?void 0:a,i=1),e=Object(e);while(++rp))return!1;var h=l.get(t),v=l.get(e);if(h&&v)return h==e&&v==t;var m=-1,g=!0,y=n&s?new r:void 0;l.set(t,e),l.set(e,t);while(++m
`,width:550,imageUrl:i(1312),imageWidth:31,imageHeight:35,showCloseButton:!0,customClass:{container:"wp-mail-smtp-swal wp-mail-smtp-upgrade-popup"},showConfirmButton:!1})}},mounted(){this.selectedMailer=this.currentMailer}},re=ne,oe=(0,d.A)(re,ie,se,!1,null,"099efe34",null),le=oe.exports,me=function(){var e=this,t=e._self._c;return t("div",{staticClass:"wp-mail-smtp-setup-wizard-step wp-mail-smtp-setup-wizard-step-configure-mailer"},[t("div",{staticClass:"wp-mail-smtp-setup-wizard-content-container"},[t("div",{staticClass:"wp-mail-smtp-configure-mailer-header"},[t("div",{staticClass:"wp-mail-smtp-configure-mailer-header-container"},[t("the-wizard-step-counter"),t("content-header",{attrs:{title:e.text_header_title,subtitle:e.text_header_subtitle}})],1),t("span",{staticClass:"wp-mail-smtp-configure-mailer-logo"},[t("inline-svg",{attrs:{src:e.logo(e.mailer),height:"40"}})],1)]),t("div",{staticClass:"wp-mail-smtp-separator wp-mail-smtp-separator-no-margin"}),t("router-view",{ref:"mailerConfiguration"})],1),t("div",{staticClass:"wp-mail-smtp-separator wp-mail-smtp-separator-no-margin"}),t("div",{staticClass:"wp-mail-smtp-setup-wizard-step-footer"},[t("a",{attrs:{href:"#"},on:{click:function(t){return t.preventDefault(),e.previousStep.apply(null,arguments)}}},[t("span",{staticClass:"text-with-arrow text-with-arrow-left"},[t("inline-svg",{staticClass:"icon",attrs:{src:i(9004),width:"16",height:"18"}}),e._v(e._s(e.text_previous_step)+" ")],1)]),t("div",{staticClass:"wp-mail-smtp-setup-wizard-step-footer-buttons"},[t("button",{staticClass:"wp-mail-smtp-button wp-mail-smtp-button-main",attrs:{type:"submit",name:"next_step",disabled:null===e.mailer||!0===e.blocked_step},on:{click:function(t){return t.preventDefault(),e.handleSubmit.apply(null,arguments)}}},[t("span",{staticClass:"text-with-arrow text-with-arrow-right"},[e._v(" "+e._s(e.text_save)+" "),t("inline-svg",{staticClass:"icon",attrs:{src:i(953),width:"16",height:"19"}})],1)])])])])},pe=[],_e=i(7860),ce={name:"WizardStepConfigureMailer",components:{ContentHeader:f,TheWizardStepCounter:j},data(){return{text_header_title:(0,l.__)("Configure Mailer Settings","wp-mail-smtp"),text_header_subtitle:(0,l.__)("Below, we'll show you all of the settings required to set up this mailer.","wp-mail-smtp"),text_save:(0,l.__)("Save and Continue","wp-mail-smtp"),text_previous_step:(0,l.__)("Previous Step","wp-mail-smtp")}},computed:{...(0,ae.L8)({mailer:"$_settings/mailer"}),...(0,_e.YP)("$_wizard",["blocked_step"])},methods:{handleSubmit(){return!this.blocked_step&&(this.$refs.mailerConfiguration.areRequiredFieldsValid()?(this.$store.dispatch("$_app/start_loading"),void this.$store.dispatch("$_settings/saveCurrentSettings").then((e=>{e.success?this.$next_step():this.$wpms_error_toast({})})).finally((()=>{this.$store.dispatch("$_app/stop_loading")}))):(this.$required_fields_modal(),!1))},previousStep(){this.blocked_step=!1,this.$previous_step()},logo(e){return"mail"===e?e="smtp":"sendinblue"===e&&(e="brevo"),i(3180)(`./${e}.svg`)}}},de=ce,ue=(0,d.A)(de,me,pe,!1,null,null,null),fe=ue.exports,he=function(){var e=this,t=e._self._c;return t("div",{staticClass:"wp-mail-smtp-setup-wizard-step wp-mail-smtp-setup-wizard-step-plugin-features"},[t("div",{staticClass:"wp-mail-smtp-setup-wizard-content-container"},[t("div",{staticClass:"wp-mail-smtp-plugin-features-header"},[t("the-wizard-step-counter"),t("content-header",{attrs:{title:e.text_header_title,subtitle:e.text_header_subtitle}})],1),t("div",{staticClass:"wp-mail-smtp-plugin-features-list"},[t("settings-input-long-checkbox",{attrs:{value:!0,name:"improved_deliverability",label:e.text_improved_email_deliverability,description:e.text_improved_email_deliverability_desc,disabled:""}}),t("settings-input-long-checkbox",{attrs:{value:!0,name:"error_tracking",label:e.text_error_tracking,description:e.text_error_tracking_desc,disabled:""}}),e.contact_form_already_installed?e._e():t("settings-input-long-checkbox",{attrs:{name:"smart_contact_form",label:e.text_smart_contact_form,description:e.text_smart_contact_form_desc},model:{value:e.smart_contact_form,callback:function(t){e.smart_contact_form=t},expression:"smart_contact_form"}}),e.is_pro?e._e():t("settings-input-long-checkbox",{attrs:{name:"summary_report_email",label:e.text_summary_report_email,description:e.text_summary_report_email_desc},model:{value:e.summary_report_email,callback:function(t){e.summary_report_email=t},expression:"summary_report_email"}}),t("settings-input-long-checkbox",{attrs:{name:"email_log",constant:"WPMS_LOGS_ENABLED",label:e.text_email_log,description:e.text_email_log_desc,show_pro:!e.is_pro},on:{input:e.emailLogEnabledChanged},model:{value:e.email_log,callback:function(t){e.email_log=t},expression:"email_log"}}),e.email_log||!e.is_pro?t("settings-input-long-checkbox",{attrs:{value:e.complete_email_report,name:"complete_email_report",label:e.text_complete_email_report,description:e.text_complete_email_report_desc,show_pro:!e.is_pro,disabled:!!e.is_pro},model:{value:e.complete_email_report,callback:function(t){e.complete_email_report=t},expression:"complete_email_report"}}):e._e(),e.is_pro&&e.email_log?t("settings-input-long-checkbox",{attrs:{name:"summary_report_email",constant:"WPMS_SUMMARY_REPORT_EMAIL_DISABLED",label:e.text_summary_report_email,description:e.text_summary_report_email_desc},model:{value:e.summary_report_email,callback:function(t){e.summary_report_email=t},expression:"summary_report_email"}}):e._e(),t("settings-input-long-checkbox",{attrs:{name:"instant_email_alert_input",label:e.text_instant_email_alert,description:e.text_instant_email_alert_desc,constant:"WPMS_ALERT_EMAIL_SEND_TO",show_pro:!e.is_pro},model:{value:e.instant_email_alert,callback:function(t){e.instant_email_alert=t},expression:"instant_email_alert"}}),e.is_pro?e._e():t("settings-input-long-checkbox",{attrs:{name:"manage_notifications",label:e.text_manage_notifications,description:e.text_manage_notifications_desc,show_pro:!e.is_pro},model:{value:e.manage_notifications,callback:function(t){e.manage_notifications=t},expression:"manage_notifications"}}),e.is_multisite&&!e.is_pro?t("settings-input-long-checkbox",{attrs:{name:"network_settings",label:e.text_network_settings,description:e.text_network_settings_desc,show_pro:!e.is_pro},model:{value:e.network_settings,callback:function(t){e.network_settings=t},expression:"network_settings"}}):e._e()],1)]),t("div",{staticClass:"wp-mail-smtp-separator wp-mail-smtp-separator-no-margin"}),t("div",{staticClass:"wp-mail-smtp-setup-wizard-step-footer"},[t("a",{attrs:{href:"#"},on:{click:function(t){return t.preventDefault(),e.previousStep.apply(null,arguments)}}},[t("span",{staticClass:"text-with-arrow text-with-arrow-left"},[t("inline-svg",{staticClass:"icon",attrs:{src:i(9004),width:"16",height:"18"}}),e._v(e._s(e.text_previous_step)+" ")],1)]),t("div",{staticClass:"wp-mail-smtp-setup-wizard-step-footer-buttons"},[t("button",{staticClass:"wp-mail-smtp-button wp-mail-smtp-button-main",attrs:{type:"submit",name:"next_step"},on:{click:function(t){return t.preventDefault(),e.handleSubmit.apply(null,arguments)}}},[t("span",{staticClass:"text-with-arrow text-with-arrow-right"},[e._v(" "+e._s(e.text_save)+" "),t("inline-svg",{staticClass:"icon",attrs:{src:i(953),width:"16",height:"19"}})],1)])])])])},ge=[],we=function(){var e=this,t=e._self._c;return t("label",{staticClass:"settings-input-long-checkbox",class:{"settings-input-long-checkbox-checked":e.value,"settings-input-long-checkbox-disabled":e.disabled||e.is_constant_set},attrs:{for:"wp-mail-smtp-settings-long-checkbox-"+e.name}},[t("div",{staticClass:"settings-input-long-checkbox-header"},[t("span",{staticClass:"title-container"},[t("span",{staticClass:"label"},[e._v(e._s(e.label))]),e.show_pro?t("inline-svg",{staticClass:"wp-mail-smtp-pro-badge",attrs:{src:i(3453),width:"46",height:"24"}}):e._e()],1),e.description?t("p",{staticClass:"description"},[e._v(e._s(e.description))]):e._e(),e.is_constant_set?t("p",{staticClass:"description description--constant",domProps:{innerHTML:e._s(e.text_constant)}}):e._e()]),t("span",{staticClass:"settings-input-long-checkbox-container"},[t("input",{attrs:{id:"wp-mail-smtp-settings-long-checkbox-"+e.name,type:"checkbox",name:e.name,disabled:e.disabled||e.is_constant_set},domProps:{checked:e.value},on:{input:function(t){return e.$emit("input",t.target.checked)}}}),t("span",{staticClass:"checkbox",class:{"checkbox-checked":e.value,"checkbox-disabled":e.disabled||e.is_constant_set}},[t("inline-svg",{staticClass:"icon",attrs:{src:i(8063),width:"16",height:"16"}})],1)])])},Ae=[],be={name:"SettingsInputLongCheckbox",props:{label:String,name:String,value:Boolean,description:String,constant:String,disabled:Boolean,show_pro:Boolean},computed:{is_constant_set:function(){return this.$wpms.defined_constants.includes(this.constant)},text_constant:function(){return(0,l.__)("This setting is already configured with the WP Mail SMTP constant. To change it, please edit or remove the "+this.constant+" constant in your wp-config.php file.","wp-mail-smtp")}}},ve=be,xe=(0,d.A)(ve,we,Ae,!1,null,null,null),ke=xe.exports,ye={name:"WizardStepPluginFeatures",components:{ContentHeader:f,TheWizardStepCounter:j,SettingsInputLongCheckbox:ke},data(){return{text_header_title:(0,l.__)("Which email features do you want to enable?","wp-mail-smtp"),text_header_subtitle:(0,l.__)("Make sure you're getting the most out of WP Mail SMTP. Just check all of the features you'd like to use, and we'll go ahead and enable those for you.","wp-mail-smtp"),text_save:(0,l.__)("Save and Continue","wp-mail-smtp"),text_previous_step:(0,l.__)("Previous Step","wp-mail-smtp"),text_improved_email_deliverability:(0,l.__)("Improved Email Deliverability","wp-mail-smtp"),text_improved_email_deliverability_desc:(0,l.__)("Ensure your emails are sent successfully and reliably.","wp-mail-smtp"),text_error_tracking:(0,l.__)("Email Error Tracking","wp-mail-smtp"),text_error_tracking_desc:(0,l.__)("Easily spot errors causing delivery issues.","wp-mail-smtp"),text_smart_contact_form:(0,l.__)("Smart Contact Form","wp-mail-smtp"),text_smart_contact_form_desc:(0,l.__)("Install the WPForms plugin and create beautiful contact forms with just a few clicks.","wp-mail-smtp"),text_email_log:(0,l.__)("Detailed Email Logs","wp-mail-smtp"),text_email_log_desc:(0,l.__)("Keep records of every email that's sent out from your website.","wp-mail-smtp"),text_instant_email_alert:(0,l.__)("Instant Email Alerts","wp-mail-smtp"),text_instant_email_alert_desc:(0,l.__)("Get notifications via email, SMS, Slack, or webhook when emails fail to send.","wp-mail-smtp"),text_complete_email_report:(0,l.__)("Complete Email Reports","wp-mail-smtp"),text_complete_email_report_desc:(0,l.__)("See the delivery status, track opens and clicks, and create deliverability graphs.","wp-mail-smtp"),text_summary_report_email:(0,l.__)("Weekly Email Summary","wp-mail-smtp"),text_summary_report_email_desc:(0,l.__)("Get statistics about emails you've sent.","wp-mail-smtp"),text_manage_notifications:(0,l.__)("Manage Default Notifications","wp-mail-smtp"),text_manage_notifications_desc:(0,l.__)("Control which email notifications your WordPress site sends.","wp-mail-smtp"),text_network_settings:(0,l.__)("Multisite Network Settings","wp-mail-smtp"),text_network_settings_desc:(0,l.__)("Save time with powerful WordPress Multisite controls.","wp-mail-smtp"),is_pro:this.$wpms.is_pro,is_multisite:this.$wpms.is_multisite,email_log:!1,complete_email_report:!!this.$wpms.is_pro,summary_report_email:!1,manage_notifications:!1,network_settings:!1}},computed:{...(0,ae.L8)({contact_form_already_installed:"$_plugins/contact_form_plugin_already_installed",email_log_setting:"$_settings/email_log_enabled",summary_report_email_setting:"$_settings/summary_report_email_enabled"}),...(0,_e.YP)("$_plugins",{smart_contact_form:"smart_contact_form_setting"}),...(0,_e.YP)("$_settings",{alert_email_connections:"settings.alert_email.connections",instant_email_alert:"settings.alert_email.enabled"})},watch:{smart_contact_form:function(){if(this.contact_form_already_installed)return!1;this.showPluginInstallFooterNotice()},contact_form_already_installed:function(){this.showPluginInstallFooterNotice()},email_log_setting:function(e){this.email_log=e},summary_report_email_setting:function(e){this.summary_report_email=e}},methods:{handleSubmit(){this.$store.dispatch("$_app/start_loading");let e=[],t={value:{general:{summary_report_email_disabled:!this.summary_report_email}}};if(e.push(this.$store.dispatch("$_settings/setSummaryReportEmail",!this.summary_report_email)),this.is_pro){t.value={...t.value,logs:{enabled:this.email_log}},e.push(this.$store.dispatch("$_settings/setLogs",this.email_log));let i={enabled:this.instant_email_alert};this.instant_email_alert&&0===Object.values(this.alert_email_connections).length&&(i.connections=[{send_to:this.$wpms.current_user_email}]),t.value={...t.value,alert_email:i}}if(e.push(this.$store.dispatch("$_settings/updateSettings",t)),e.push(Promise.resolve({success:!0}).then((e=>this.smart_contact_form&&!this.contact_form_already_installed?this.$store.dispatch("$_plugins/installPlugin","wpforms-lite"):e))),!this.is_pro){const t=[];this.email_log&&t.push("email_log"),this.complete_email_report&&t.push("complete_email_report"),this.instant_email_alert&&t.push("instant_email_alert"),this.manage_notifications&&t.push("manage_notifications"),this.network_settings&&t.push("network_settings"),e.push(this.$store.dispatch("$_settings/savePluginFeatures",t))}Promise.all(e).then((e=>{const t=e.filter((e=>e.success));if(t.length===e.length){this.$emit("displayContentBelow","");let e=this.is_pro&&!this.$store.getters["$_settings/email_log_enabled"]?1:0;this.$next_step(e)}})).finally((()=>{this.$store.dispatch("$_app/stop_loading")}))},previousStep(){this.$emit("displayContentBelow","");const e=this.$wizard_steps.findIndex((e=>this.$route.name.includes(e)))-1;this.$router.push({name:`${this.$wizard_steps[e]}_${this.$store.getters["$_settings/mailer"]}`})},showPluginInstallFooterNotice(){let e=[];this.smart_contact_form&&!this.contact_form_already_installed&&e.push("WPForms");let t="";e.length>0&&(t=(0,l.__)("The following plugin will be installed for free:","wp-mail-smtp"),t=`
${t} ${e.join(", ")}
`),this.$emit("displayContentBelow",t)},emailLogEnabledChanged(){"0"===this.$wpms.completed_time&&sessionStorage.setItem("wp_mail_smtp_email_log_enabled_changed","true")}},mounted(){if(this.showPluginInstallFooterNotice(),this.$wpms.is_pro&&"0"===this.$wpms.completed_time&&"true"!==sessionStorage.getItem("wp_mail_smtp_email_log_enabled_changed")?this.email_log=!0:this.email_log=this.$store.getters["$_settings/email_log_enabled"],this.summary_report_email=this.$store.getters["$_settings/summary_report_email_enabled"],!this.$wpms.is_pro){const e=this.$store.getters["$_settings/plugin_features"];e.includes("email_log")&&(this.email_log=!0),e.includes("complete_email_report")&&(this.complete_email_report=!0),e.includes("instant_email_alert")&&(this.instant_email_alert=!0),e.includes("manage_notifications")&&(this.manage_notifications=!0),e.includes("network_settings")&&(this.network_settings=!0)}}},Ce=ye,Se=(0,d.A)(Ce,he,ge,!1,null,null,null),Me=Se.exports,Pe=function(){var e=this,t=e._self._c;return t("div",{staticClass:"wp-mail-smtp-setup-wizard-step wp-mail-smtp-setup-wizard-step-help-improve"},[t("div",{staticClass:"wp-mail-smtp-setup-wizard-content-container"},[t("div",{staticClass:"wp-mail-smtp-help-improve-header"},[t("the-wizard-step-counter"),t("content-header",{attrs:{title:e.text_header_title,subtitle:e.text_header_subtitle}})],1),t("settings-input-text",{attrs:{name:"email",type:"email",label:e.text_email_label,description:e.text_email_description},model:{value:e.current_user_email,callback:function(t){e.current_user_email=t},expression:"current_user_email"}}),t("settings-input-checkbox",{attrs:{name:"usage_tracking",label:e.text_usage_tracking_label,description:e.text_usage_tracking_description,tooltip:e.text_usage_tracking_tooltip},model:{value:e.usage_tracking,callback:function(t){e.usage_tracking=t},expression:"usage_tracking"}})],1),t("div",{staticClass:"wp-mail-smtp-separator wp-mail-smtp-separator-no-margin"}),t("div",{staticClass:"wp-mail-smtp-setup-wizard-step-footer"},[t("a",{attrs:{href:"#"},on:{click:function(t){return t.preventDefault(),e.previousStep.apply(null,arguments)}}},[t("span",{staticClass:"text-with-arrow text-with-arrow-left"},[t("inline-svg",{staticClass:"icon",attrs:{src:i(9004),width:"16",height:"18"}}),e._v(e._s(e.text_previous_step)+" ")],1)]),t("div",{staticClass:"wp-mail-smtp-setup-wizard-step-footer-buttons"},[t("button",{staticClass:"wp-mail-smtp-button",attrs:{type:"button",name:"skip_step"},domProps:{textContent:e._s(e.text_skip)},on:{click:function(t){return t.preventDefault(),e.nextStep.apply(null,arguments)}}}),t("button",{staticClass:"wp-mail-smtp-button wp-mail-smtp-button-main",attrs:{type:"submit",name:"next_step"},on:{click:function(t){return t.preventDefault(),e.handleSubmit.apply(null,arguments)}}},[t("span",{staticClass:"text-with-arrow text-with-arrow-right"},[e._v(" "+e._s(e.text_save)+" "),t("inline-svg",{staticClass:"icon",attrs:{src:i(953),width:"16",height:"19"}})],1)])])])])},Ee=[],Fe=function(){var e=this,t=e._self._c;return t("div",{staticClass:"settings-input-text",class:{"settings-input-text-with-copy":e.copy,"input-error":e.has_errors||e.field_error}},[t("label",{staticClass:"settings-input-label-container",attrs:{for:e.id}},[e.label?t("span",{staticClass:"label",domProps:{innerHTML:e._s(e.label)}}):e._e(),e.tooltip?t("settings-info-tooltip",{attrs:{content:e.tooltip}}):e._e()],1),t("span",{staticClass:"settings-input-container"},["checkbox"===e.type?t("input",{directives:[{name:"model",rawName:"v-model",value:e.currentValue,expression:"currentValue"}],ref:"input",attrs:{id:e.id,name:e.name,placeholder:e.placeholder,readonly:e.readonly,disabled:e.disabled||e.is_constant_set,type:"checkbox"},domProps:{checked:Array.isArray(e.currentValue)?e._i(e.currentValue,null)>-1:e.currentValue},on:{change:[function(t){var i=e.currentValue,s=t.target,a=!!s.checked;if(Array.isArray(i)){var n=null,r=e._i(i,n);s.checked?r<0&&(e.currentValue=i.concat([n])):r>-1&&(e.currentValue=i.slice(0,r).concat(i.slice(r+1)))}else e.currentValue=a},e.inputUpdate]}}):"radio"===e.type?t("input",{directives:[{name:"model",rawName:"v-model",value:e.currentValue,expression:"currentValue"}],ref:"input",attrs:{id:e.id,name:e.name,placeholder:e.placeholder,readonly:e.readonly,disabled:e.disabled||e.is_constant_set,type:"radio"},domProps:{checked:e._q(e.currentValue,null)},on:{change:[function(t){e.currentValue=null},e.inputUpdate]}}):t("input",{directives:[{name:"model",rawName:"v-model",value:e.currentValue,expression:"currentValue"}],ref:"input",attrs:{id:e.id,name:e.name,placeholder:e.placeholder,readonly:e.readonly,disabled:e.disabled||e.is_constant_set,type:e.type},domProps:{value:e.currentValue},on:{change:e.inputUpdate,input:function(t){t.target.composing||(e.currentValue=t.target.value)}}}),e.copy?t("button",{staticClass:"wp-mail-smtp-button wp-mail-smtp-button-small",class:{"wp-mail-smtp-button-copied":e.show_copied},attrs:{title:e.text_copy_button},on:{click:function(t){return t.preventDefault(),e.copyValue.apply(null,arguments)}}},[t("span",{staticClass:"copy-button-container"},[t("inline-svg",{staticClass:"icon",class:{active:!e.show_copied},attrs:{src:i(7726),width:"16",height:"16"}}),t("inline-svg",{staticClass:"icon copied",class:{active:e.show_copied},attrs:{src:i(2452),width:"16",height:"16"}})],1)]):e._e()]),e.has_errors?t("p",{staticClass:"error"},[t("inline-svg",{staticClass:"icon",attrs:{src:i(617),width:"16"}}),t("span",{domProps:{innerHTML:e._s(e.text_error)}})],1):e._e(),e.description?t("p",{staticClass:"description",domProps:{innerHTML:e._s(e.description)}}):e._e(),e.is_constant_set?t("p",{staticClass:"description description--constant",domProps:{innerHTML:e._s(e.text_constant)}}):e._e()])},Be=[],Te=function(){var e=this,t=e._self._c;return t("span",{directives:[{name:"tooltip",rawName:"v-tooltip",value:e.tooltip_data,expression:"tooltip_data"}],staticClass:"wp-mail-smtp-info",attrs:{tabindex:"0"}},[t("inline-svg",{staticClass:"icon",attrs:{src:i(5414),width:"14",height:"14"}})],1)},Ie=[],De={name:"SettingsInfoTooltip",props:{content:String},data(){return{tooltip_data:{content:this.content,autoHide:!1,trigger:"hover focus click"}}}},Oe=De,ze=(0,d.A)(Oe,Te,Ie,!1,null,"74a4d2ae",null),Le=ze.exports,Re={name:"SettingsInputText",components:{SettingsInfoTooltip:Le},props:{name:String,value:String,label:String,description:String,constant:String,placeholder:String,type:{type:String,default:"text"},tooltip:String,readonly:Boolean,disabled:Boolean,format:RegExp,error:{type:String,default:""},copy:{type:Boolean,default:!1},is_error:Boolean},data(){return{has_error:!1,id:"input-"+this.name,text_copy_button:(0,l.__)("Copy input value","wp-mail-smtp"),text_copied:(0,l.__)("Copied!","wp-mail-smtp"),show_copied:!1}},computed:{currentValue:{get(){return this.value},set(e){this.$emit("is_error_update",!1),this.$emit("input",e)}},field_error:{get(){return this.is_error},set(e){this.$emit("is_error_update",e)}},has_errors:function(){return this.error.length>0||this.has_error},text_error:function(){return this.error.length>0?this.error:(0,l.__)("The value entered does not match the required format","wp-mail-smtp")},is_constant_set:function(){return this.$wpms.defined_constants.includes(this.constant)},text_constant:function(){return(0,l.__)("This setting is already configured with the WP Mail SMTP constant. To change it, please edit or remove the "+this.constant+" constant in your wp-config.php file.","wp-mail-smtp")}},methods:{inputUpdate:function(e){if(this.disabled)return!1;if(this.has_error=!1,this.format||this.type&&"email"===this.type){const t=this.format?this.format:/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;if(!t.test(e.target.value))return this.has_error=!0,this.$emit("error_detected",this.text_error),!1}},copyValue:function(){const e=this.$refs.input;e.select(),document.execCommand("copy"),this.show_copied=!0;let t=this;setTimeout((function(){t.show_copied=!1}),1e3)}}},We=Re,Ne=(0,d.A)(We,Fe,Be,!1,null,null,null),Ue=Ne.exports,Qe=function(){var e=this,t=e._self._c;return t("div",{staticClass:"settings-input-checkbox",class:{"settings-input-checkbox-checked":e.value,"settings-input-checkbox-disabled":e.disabled}},[t("span",{staticClass:"settings-input-label-container"},[t("span",{staticClass:"label"},[e._v(e._s(e.label))]),e.tooltip?t("settings-info-tooltip",{attrs:{content:e.tooltip}}):e._e()],1),t("label",{staticClass:"settings-input-checkbox-container",attrs:{for:"wp-mail-smtp-settings-checkbox-"+e.name}},[t("input",{attrs:{id:"wp-mail-smtp-settings-checkbox-"+e.name,type:"checkbox",name:e.name,disabled:e.disabled},domProps:{checked:e.value},on:{input:function(t){return e.$emit("input",t.target.checked)}}}),t("span",{staticClass:"checkbox",class:{"checkbox-checked":e.value,"checkbox-disabled":e.disabled}},[t("inline-svg",{staticClass:"icon",attrs:{src:i(8063),width:"14",height:"14"}})],1),e.description?t("span",{staticClass:"input-label"},[e._v(e._s(e.description))]):e._e()])])},Ze=[],Ge={name:"SettingsInputCheckbox",components:{SettingsInfoTooltip:Le},props:{label:String,name:String,value:Boolean,description:String,tooltip:String,disabled:Boolean}},Ye=Ge,He=(0,d.A)(Ye,Qe,Ze,!1,null,null,null),Ve=He.exports,Ke={name:"WizardStepHelpImprove",components:{ContentHeader:f,TheWizardStepCounter:j,SettingsInputText:Ue,SettingsInputCheckbox:Ve},data(){return{text_header_title:(0,l.__)("Help Improve WP Mail SMTP + Smart Recommendations","wp-mail-smtp"),text_header_subtitle:(0,l.__)("Get helpful suggestions from WP Mail SMTP on how to optimize your email deliverability and grow your business.","wp-mail-smtp"),text_save:(0,l.__)("Save and Continue","wp-mail-smtp"),text_skip:(0,l.__)("Skip this Step","wp-mail-smtp"),text_previous_step:(0,l.__)("Previous Step","wp-mail-smtp"),text_email_label:(0,l.__)("Your Email Address","wp-mail-smtp"),text_email_description:(0,l.__)("Your email is needed, so you can receive recommendations.","wp-mail-smtp"),text_usage_tracking_label:(0,l.__)("Help make WP Mail SMTP better for everyone","wp-mail-smtp"),text_usage_tracking_description:(0,l.__)("Yes, count me in","wp-mail-smtp"),text_usage_tracking_tooltip:(0,l.__)("By allowing us to track usage data we can better help you because we know with which WordPress configurations, themes and plugins we should test.","wp-mail-smtp"),is_pro:this.$wpms.is_pro,usage_tracking:!1}},computed:{...(0,_e.YP)("$_wizard",["current_user_email"])},methods:{handleSubmit(){this.$store.dispatch("$_app/start_loading");let e=[];if(this.current_user_email&&e.push(this.$store.dispatch("$_settings/subscribeToNewsletter",this.current_user_email)),this.usage_tracking){const t={value:{general:{"usage-tracking-enabled":!0}}};e.push(this.$store.dispatch("$_settings/updateSettings",t))}Promise.all(e).then((()=>{this.nextStep()})).finally((()=>{this.$store.dispatch("$_app/stop_loading")}))},nextStep(){this.$next_step()},previousStep(){this.$previous_step()}}},qe=Ke,Je=(0,d.A)(qe,Pe,Ee,!1,null,null,null),je=Je.exports,Xe=function(){var e=this,t=e._self._c;return t("div",{staticClass:"wp-mail-smtp-setup-wizard-step wp-mail-smtp-setup-wizard-step-license"},[t("div",{staticClass:"wp-mail-smtp-setup-wizard-content-container"},[t("div",{staticClass:"wp-mail-smtp-license-header"},[t("the-wizard-step-counter"),t("content-header",{attrs:{title:e.text_header_title,subtitle:e.text_header_subtitle}})],1),e.is_pro?e._e():t("div",{staticClass:"upgrade-content"},[t("p",{staticClass:"medium-bold",domProps:{innerHTML:e._s(e.text_upgrade_paragraph)}}),t("div",{staticClass:"checked-item-list"},[t("span",{staticClass:"checked-item"},[t("inline-svg",{staticClass:"icon",attrs:{src:i(8063),width:"16",height:"16"}}),e._v(" "),t("span",[e._v(e._s(e.text_email_log))])],1),t("span",{staticClass:"checked-item"},[t("inline-svg",{staticClass:"icon",attrs:{src:i(8063),width:"16",height:"16"}}),e._v(" "),t("span",[e._v(e._s(e.text_complete_email_report))])],1),t("span",{staticClass:"checked-item"},[t("inline-svg",{staticClass:"icon",attrs:{src:i(8063),width:"16",height:"16"}}),e._v(" "),t("span",[e._v(e._s(e.text_instant_email_alert))])],1),t("span",{staticClass:"checked-item"},[t("inline-svg",{staticClass:"icon",attrs:{src:i(8063),width:"16",height:"16"}}),e._v(" "),t("span",[e._v(e._s(e.text_summary_report_email))])],1),t("span",{staticClass:"checked-item"},[t("inline-svg",{staticClass:"icon",attrs:{src:i(8063),width:"16",height:"16"}}),e._v(" "),t("span",[e._v(e._s(e.text_manage_notifications))])],1),t("span",{staticClass:"checked-item"},[t("inline-svg",{staticClass:"icon",attrs:{src:i(8063),width:"16",height:"16"}}),e._v(" "),t("span",[e._v(e._s(e.text_network_settings))])],1)])]),e.verified?t("div",{staticClass:"verified-license"},[t("p",{domProps:{innerHTML:e._s(e.text_verified_license)}})]):t("div",{staticClass:"license-form",class:{"license-form-error":e.license_error}},[t("p",{domProps:{innerHTML:e._s(e.text_license_form)}}),t("div",{staticClass:"license-control"},[t("input",{directives:[{name:"model",rawName:"v-model",value:e.license,expression:"license"}],attrs:{name:"license",type:"password",placeholder:e.text_license_input_placeholder,"aria-label":e.text_aria_label_for_license_input},domProps:{value:e.license},on:{input:function(t){t.target.composing||(e.license=t.target.value)}}}),t("button",{staticClass:"wp-mail-smtp-button wp-mail-smtp-button-success wp-mail-smtp-button-small",attrs:{type:"button"},on:{click:function(t){return t.preventDefault(),e.handleLicenseSubmit.apply(null,arguments)}}},[e._v(" "+e._s(e.text_license_button)+" ")])]),e.license_error?t("p",{staticClass:"error-message",domProps:{textContent:e._s(e.text_license_error)}}):e._e()])]),t("div",{staticClass:"wp-mail-smtp-separator wp-mail-smtp-separator-no-margin"}),t("div",{staticClass:"wp-mail-smtp-setup-wizard-step-footer"},[t("a",{attrs:{href:"#"},on:{click:function(t){return t.preventDefault(),e.previousStep.apply(null,arguments)}}},[t("span",{staticClass:"text-with-arrow text-with-arrow-left"},[t("inline-svg",{staticClass:"icon",attrs:{src:i(9004),width:"16",height:"18"}}),e._v(e._s(e.text_previous_step)+" ")],1)]),t("div",{staticClass:"wp-mail-smtp-setup-wizard-step-footer-buttons"},[e.verified?t("button",{staticClass:"wp-mail-smtp-button wp-mail-smtp-button-main",attrs:{type:"submit",name:"next_step"},on:{click:function(t){return t.preventDefault(),e.handleSubmit.apply(null,arguments)}}},[t("span",{staticClass:"text-with-arrow text-with-arrow-right"},[e._v(" "+e._s(e.text_save)+" "),t("inline-svg",{staticClass:"icon",attrs:{src:i(953),width:"16",height:"19"}})],1)]):t("button",{staticClass:"wp-mail-smtp-button",attrs:{type:"button",name:"skip_step"},domProps:{textContent:e._s(e.text_skip)},on:{click:function(t){return t.preventDefault(),e.nextStep.apply(null,arguments)}}})])])])},$e=[],et=i(470),tt=i.n(et),it={name:"WizardStepLicense",components:{ContentHeader:f,TheWizardStepCounter:j},data(){return{text_header_title:(0,l.__)("Enter your WP Mail SMTP License Key","wp-mail-smtp"),text_header_subtitle:this.$wpms.is_pro?"":(0,l.nv)((0,l.__)("You're currently using %1$sWP Mail SMTP Lite%2$s - no license needed. Enjoy!","wp-mail-smtp"),'',"")+" š",text_save:(0,l.__)("Continue","wp-mail-smtp"),text_skip:(0,l.__)("Skip this Step","wp-mail-smtp"),text_previous_step:(0,l.__)("Previous Step","wp-mail-smtp"),text_upgrade_paragraph:(0,l.nv)((0,l.__)("To unlock selected features, %1$sUpgrade to Pro%2$s and enter your license key below.","wp-mail-smtp"),'',""),text_network_settings:(0,l.__)("Multisite Network Settings","wp-mail-smtp"),text_manage_notifications:(0,l.__)("Manage Default Notifications","wp-mail-smtp"),text_email_log:(0,l.__)("Detailed Email Logs","wp-mail-smtp"),text_summary_report_email:(0,l.__)("Enhanced Weekly Email Summary","wp-mail-smtp"),text_license_form_lite:(0,l.nv)((0,l.__)("Already purchased? Enter your license key below to connect with %1$sWP Mail SMTP Pro%2$s!","wp-mail-smtp"),"",""),text_license_form_pro:(0,l.__)("Enter your license key below to unlock plugin updates!","wp-mail-smtp"),text_license_button:this.$wpms.is_pro?(0,l.__)("Verify License Key","wp-mail-smtp"):(0,l.__)("Connect","wp-mail-smtp"),text_license_error:(0,l.__)("The License Key format is incorrect. Please enter a valid key and try again.","wp-mail-smtp"),text_verified_license:(0,l.__)("Your license was successfully verified! You are ready for the next step.","wp-mail-smtp"),text_email_log_desc:(0,l.__)("Keep records of every email that's sent out from your website.","wp-mail-smtp"),text_manage_notifications_desc:(0,l.__)("Control which email notifications your WordPress site sends.","wp-mail-smtp"),text_network_settings_desc:(0,l.__)("Save time with powerful WordPress Multisite controls.","wp-mail-smtp"),text_instant_email_alert:(0,l.__)("Instant Email Alerts","wp-mail-smtp"),text_instant_email_alert_desc:(0,l.__)("Get notifications via email, SMS, Slack, or webhook when emails fail to send.","wp-mail-smtp"),text_complete_email_report:(0,l.__)("Complete Email Reports","wp-mail-smtp"),text_complete_email_report_desc:(0,l.__)("See the delivery status, track opens and clicks, and create deliverability graphs.","wp-mail-smtp"),text_pro_badge:(0,l.__)("Pro badge","wp-mail-smtp"),text_aria_label_for_license_input:(0,l.__)("License key input","wp-mail-smtp"),text_license_input_placeholder:(0,l.__)("Paste your license key here","wp-mail-smtp"),pro_badge:i(3453),is_pro:this.$wpms.is_pro,verified:!1,license:"",license_error:!1}},computed:{text_license_form:function(){return this.is_pro?this.text_license_form_pro:this.text_license_form_lite},...(0,ae.L8)({selectedProFeatures:"$_settings/plugin_features"})},methods:{handleLicenseSubmit(){return this.license_error=!1,!(!this.is_pro&&0===this.license.length)&&(this.is_pro&&this.license.length<16?(this.license_error=!0,!1):(this.$store.dispatch("$_app/start_loading"),void(this.is_pro?this.$store.dispatch("$_settings/verifyLicense",this.license).then((e=>{e.success?(this.verified=!0,this.$swal({title:(0,l.__)("Successful Verification!","wp-mail-smtp"),html:e.data.message,width:450,showCloseButton:!0,customClass:{container:"wp-mail-smtp-swal wp-mail-smtp-swal-alert"}})):this.$swal({title:(0,l.__)("Verification Error!","wp-mail-smtp"),html:e.data,width:450,showCloseButton:!0,customClass:{container:"wp-mail-smtp-swal wp-mail-smtp-swal-alert"}})})).finally((()=>{this.$store.dispatch("$_app/stop_loading")})):this.$store.dispatch("$_settings/upgradePlugin",this.license).then((e=>{if(e.success&&tt()(e,"data.redirect_url"))return window.location=e.data.redirect_url;this.$store.dispatch("$_app/stop_loading"),this.$swal({title:e.success?(0,l.__)("Successful Upgrade!","wp-mail-smtp"):(0,l.__)("Upgrade Failed!","wp-mail-smtp"),html:e.data,width:450,showCloseButton:!0,customClass:{container:"wp-mail-smtp-swal wp-mail-smtp-swal-alert"}})})))))},handleSubmit(){this.nextStep()},nextStep(){this.$next_step()},previousStep(){let e=this.is_pro&&!this.$store.getters["$_settings/email_log_enabled"]?1:0;this.$previous_step(e)},prepareLongCheckbox(e,t){return``},prepareProFeaturesHtml(){let e="
"}},mounted(){if(!this.is_pro&&this.selectedProFeatures.length>0){const e=this.prepareProFeaturesHtml();this.$swal({title:(0,l.__)("Would you like to purchase the following features now?","wp-mail-smtp"),html:`
${(0,l.__)("These features are available as part of WP Mail SMTP Pro plan.","wp-mail-smtp")}
\n\t\t\t\t\t\t\t${e}\n\t\t\t\t\t\t\t
${(0,l.nv)((0,l.__)("%1$sBonus:%2$s You can upgrade to the Pro plan and %3$ssave %5$s today%4$s, automatically applied at checkout.","wp-mail-smtp"),"","",'',"","$50")}
\n\t\t\t\t\t\t`,width:850,showCloseButton:!0,allowOutsideClick:!1,allowEscapeKey:!1,allowEnterKey:!1,customClass:{container:"wp-mail-smtp-swal wp-mail-smtp-swal-plugin-upgrade"},confirmButtonText:(0,l.__)("Purchase Now","wp-mail-smtp"),cancelButtonText:(0,l.__)("I'll do it later","wp-mail-smtp"),showCancelButton:!0,reverseButtons:!0}).then((e=>{if(e.value){const e=window.open(this.$wpms.upgrade_link,"_blank");e.focus()}}))}this.verified=this.$wpms.license_exists},created(){const e=new URLSearchParams(window.location.search);this.$wpms.license_exists&&!e.has("upgrade-redirect")&&this.nextStep()}},st=it,at=(0,d.A)(st,Xe,$e,!1,null,null,null),nt=at.exports,rt=function(){var e=this,t=e._self._c;return t("div",{staticClass:"wp-mail-smtp-setup-wizard-step wp-mail-smtp-setup-wizard-check-configuration"},[t("div",{staticClass:"wp-mail-smtp-setup-wizard-content-container"},[t("div",{staticClass:"wp-mail-smtp-check-configuration-header"},[t("content-header",{attrs:{title:e.text_header_title,subtitle:e.text_header_subtitle}})],1),t("div",{staticClass:"check-configuration-loading-image-container"},[t("img",{attrs:{src:i(6915),alt:e.text_image_alt}})])])])},ot=[],lt={name:"WizardStepCheckConfiguration",components:{ContentHeader:f},data(){return{text_header_title:(0,l.__)("Checking Mailer Configuration","wp-mail-smtp"),text_header_subtitle:(0,l.__)("We're running some tests in the background to make sure everything is set up properly.","wp-mail-smtp"),text_image_alt:(0,l.__)("Checking mailer configuration image","wp-mail-smtp")}},mounted(){this.$store.dispatch("$_wizard/checkMailerConfiguration").then((e=>{e.success?this.$router.push({name:"check_configuration_step_success"}):this.$router.push({name:"check_configuration_step_failure"})}))}},mt=lt,pt=(0,d.A)(mt,rt,ot,!1,null,null,null),_t=pt.exports,ct=function(){var e=this,t=e._self._c;return t("div",{staticClass:"wp-mail-smtp-setup-wizard-step wp-mail-smtp-setup-wizard-configuration-success"},[t("div",{staticClass:"wp-mail-smtp-setup-wizard-content-container"},[t("div",{staticClass:"wp-mail-smtp-configuration-success-header"},[t("the-wizard-step-counter"),t("content-header",{attrs:{title:e.text_header_title,subtitle:e.text_header_subtitle}})],1),t("div",{staticClass:"plugin-item-container"},[t("p",{staticClass:"medium-bold",domProps:{textContent:e._s(e.text_free_plugins_header)}}),t("div",e._l(e.plugins,(function(e,i){return t("plugin-item",{key:i,attrs:{name:e.name,slug:e.slug,is_installed:e.is_installed,is_activated:e.is_activated}})})),1)]),e.is_pro?e._e():t("div",{staticClass:"upgrade-banner-container"},[t("div",{staticClass:"upgrade-banner"},[t("h2",{domProps:{textContent:e._s(e.text_upgrade_title)}}),t("p",{staticClass:"subtitle",domProps:{textContent:e._s(e.text_upgrade_subtitle)}}),t("div",{staticClass:"checked-item-list"},[t("span",{staticClass:"checked-item"},[t("inline-svg",{staticClass:"icon",attrs:{src:i(8063),width:"16",height:"16"}}),e._v(" "),t("span",[e._v(e._s(e.text_email_log))])],1),t("span",{staticClass:"checked-item"},[t("inline-svg",{staticClass:"icon",attrs:{src:i(8063),width:"16",height:"16"}}),e._v(" "),t("span",[e._v(e._s(e.text_manage_notifications))])],1),t("span",{staticClass:"checked-item"},[t("inline-svg",{staticClass:"icon",attrs:{src:i(8063),width:"16",height:"16"}}),e._v(" "),t("span",[e._v(e._s(e.text_network_settings))])],1)]),t("button",{staticClass:"wp-mail-smtp-button wp-mail-smtp-button-success",attrs:{type:"button"},domProps:{textContent:e._s(e.text_upgrade_button)},on:{click:e.openUpgradePage}})]),t("p",{staticClass:"bonus",domProps:{innerHTML:e._s(e.text_bonus)}})])]),t("div",{staticClass:"wp-mail-smtp-separator wp-mail-smtp-separator-no-margin"}),t("div",{staticClass:"wp-mail-smtp-setup-wizard-step-footer"},[t("button",{staticClass:"wp-mail-smtp-button",attrs:{type:"button",name:"send_test_email"},domProps:{textContent:e._s(e.text_test_email)},on:{click:function(t){return t.preventDefault(),e.handleTestEmail.apply(null,arguments)}}}),t("button",{staticClass:"wp-mail-smtp-button",attrs:{type:"button",name:"send_feedback"},domProps:{textContent:e._s(e.text_send_feedback)},on:{click:function(t){return t.preventDefault(),e.handleFeedback.apply(null,arguments)}}}),t("button",{staticClass:"wp-mail-smtp-button wp-mail-smtp-button-main",attrs:{type:"button",name:"finish_setup"},domProps:{textContent:e._s(e.text_finish)},on:{click:function(t){return t.preventDefault(),e.handleFinish.apply(null,arguments)}}})])])},dt=[],ut=function(){var e=this,t=e._self._c;return t("div",{class:`wp-mail-smtp-plugin-item wp-mail-smtp-plugin-${e.slug}`},[t("span",{staticClass:"wp-mail-smtp-plugin-item-title-container"},[e.logo.length?t("img",{staticClass:"wp-mail-smtp-logo-icon",attrs:{src:e.logo2x,srcset:e.logo_srcset,alt:e.name}}):e._e(),t("span",{domProps:{textContent:e._s(e.name)}})]),t("button",{staticClass:"wp-mail-smtp-button",attrs:{type:"button",disabled:e.is_activated||e.is_installed},on:{click:function(t){return t.preventDefault(),e.handleClick.apply(null,arguments)}}},[e.loading?t("spin-loader",{attrs:{color:"white"}}):t("span",[e._v(" "+e._s(e.text_button_label)+" ")])],1)])},ft=[],ht=function(){var e=this,t=e._self._c;return t("img",{class:`wp-mail-smtp-loader wp-mail-smtp-loader-${e.size}`,attrs:{src:e.image,alt:e.text_loading}})},gt=[],wt={name:"SpinLoader",props:{color:{type:String,default:""},size:{type:String,default:"sm"}},data(){return{image:i(3159)(`./loading${this.color.length?"-"+this.color:""}.svg`),text_loading:(0,l.__)("Loading","wp-mail-smtp")}}},At=wt,bt=(0,d.A)(At,ht,gt,!1,null,null,null),vt=bt.exports,xt={name:"PluginItem",components:{SpinLoader:vt},props:{slug:String,name:String,is_installed:Boolean,is_activated:Boolean},data(){return{loading:!1,logo:i(1584)(`./${this.slug}.png`),logo2x:i(3962)(`./${this.slug}@2x.png`)}},computed:{text_button_label:function(){let e=(0,l.__)("Install","wp-mail-smtp");return this.is_installed&&!this.is_activated&&(e=(0,l.__)("Installed","wp-mail-smtp")),this.is_activated&&(e=(0,l.__)("Activated","wp-mail-smtp")),e},logo_srcset:function(){return`${this.logo}, ${this.logo2x} 2x`}},methods:{handleClick(){this.loading||(this.loading=!0,this.$store.dispatch("$_plugins/installPlugin",this.slug).then((e=>{e.success&&this.$wpms_success_toast({title:`Plugin: ${this.name} installed!`}),this.loading=!1})))}}},kt=xt,yt=(0,d.A)(kt,ut,ft,!1,null,"2e2edfa6",null),Ct=yt.exports,St={name:"WizardStepConfigurationSuccess",components:{ContentHeader:f,TheWizardStepCounter:j,PluginItem:Ct},data(){return{text_header_title:(0,l.__)("Congrats, youāve successfully set up WP Mail SMTP!","wp-mail-smtp"),text_header_subtitle:(0,l.__)("Hereās what to do next:","wp-mail-smtp"),text_free_plugins_header:(0,l.__)("Check out our other free WordPress plugins:","wp-mail-smtp"),text_upgrade_title:(0,l.__)("Upgrade to Unlock Powerful SMTP Features","wp-mail-smtp"),text_upgrade_subtitle:(0,l.__)("Upgrade to WP Mail SMTP Pro to unlock more awesome features and experience why WP Mail SMTP is used by over 4,000,000 websites.","wp-mail-smtp"),text_network_settings:(0,l.__)("Multisite Network Settings","wp-mail-smtp"),text_manage_notifications:(0,l.__)("Manage Default Notifications","wp-mail-smtp"),text_email_log:(0,l.__)("Detailed Email Logs","wp-mail-smtp"),text_upgrade_button:(0,l.__)("Upgrade to Pro Today","wp-mail-smtp"),text_test_email:(0,l.__)("Send a Test Email","wp-mail-smtp"),text_send_feedback:(0,l.__)("Send us Feedback","wp-mail-smtp"),text_finish:(0,l.__)("Finish Setup","wp-mail-smtp"),text_bonus:(0,l.nv)((0,l.__)("%1$sBonus:%2$s You can upgrade to the Pro plan and %3$ssave %5$s today%4$s, automatically applied at checkout.","wp-mail-smtp"),"","",'',"","$50"),star_image_html:``,is_pro:this.$wpms.is_pro}},computed:{...(0,ae.L8)({plugins:"$_plugins/partner_plugins"})},methods:{handleTestEmail(){return window.location=this.$wpms.email_test_tab_url},goodFeedback(){this.$swal({title:(0,l.__)("Thanks for the feedback!","wp-mail-smtp"),html:`${(0,l.nv)((0,l.__)("Help us spread the word %1$sby giving WP Mail SMTP a 5-star rating %3$s(%4$s) on WordPress.org%2$s. Thanks for your support and we look forward to bringing you more awesome features.","wp-mail-smtp"),'',""," ",this.star_image_html+""+this.star_image_html+this.star_image_html+this.star_image_html+this.star_image_html)}`,width:650,showCloseButton:!0,allowEnterKey:!1,confirmButtonText:(0,l.__)("Rate on WordPress.org","wp-mail-smtp"),customClass:{container:"wp-mail-smtp-swal wp-mail-smtp-swal-feedback-good"}}).then((e=>{if(e.value){const e=window.open("https://wordpress.org/support/plugin/wp-mail-smtp/reviews/#new-post","_blank");e.focus()}}))},badFeedback(){this.$swal({title:(0,l.__)("What could we do to improve?","wp-mail-smtp"),html:`${(0,l.__)("We're sorry things didn't go smoothly for you, and want to keep improving. Please let us know any specific parts of this process that you think could be better. We really appreciate any details you're willing to share!","wp-mail-smtp")}\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t`,width:650,showCloseButton:!0,allowEnterKey:!1,allowOutsideClick:!1,allowEscapeKey:!1,confirmButtonText:(0,l.__)("Submit Feedback","wp-mail-smtp"),customClass:{container:"wp-mail-smtp-swal wp-mail-smtp-swal-feedback-bad"},preConfirm:()=>[document.getElementById("feedback").value,document.getElementById("permission").checked]}).then((e=>{if(e.value){const t=e.value[0],i=e.value[1];this.$store.dispatch("$_wizard/sendFeedback",{feedback:t,permission:i})}}))},handleFeedback(){this.$swal({title:(0,l.__)("How was your WP Mail SMTP setup experience?","wp-mail-smtp"),text:(0,l.__)("Our goal is to make your SMTP setup as simple and straightforward as possible. We'd love to know how this process went for you!","wp-mail-smtp"),width:650,showCloseButton:!0,allowEnterKey:!1,customClass:{container:"wp-mail-smtp-swal wp-mail-smtp-swal-feedback"},showCancelButton:!0}).then((e=>{e.value?this.goodFeedback():void 0!==e.dismiss&&"cancel"===e.dismiss&&this.badFeedback()}))},handleFinish(){return window.location=this.$wpms.exit_url},openUpgradePage:function(){const e=window.open(this.$wpms.upgrade_link,"_blank");e.focus()}}},Mt=St,Pt=(0,d.A)(Mt,ct,dt,!1,null,null,null),Et=Pt.exports,Ft=function(){var e=this,t=e._self._c;return t("div",{staticClass:"wp-mail-smtp-setup-wizard-step wp-mail-smtp-setup-wizard-configuration-failure"},[t("div",{staticClass:"wp-mail-smtp-setup-wizard-content-container"},[t("div",{staticClass:"wp-mail-smtp-configuration-failure-header"},[t("the-wizard-step-counter"),t("content-header",{attrs:{title:e.text_header_title,subtitle:e.text_header_subtitle}})],1),t("div",{staticClass:"start-troubleshooting-arrow-container"},[t("inline-svg",{staticClass:"icon",attrs:{src:i(5573),width:"112",height:"112"}})],1)]),t("div",{staticClass:"wp-mail-smtp-separator wp-mail-smtp-separator-no-margin"}),t("div",{staticClass:"wp-mail-smtp-setup-wizard-step-footer"},[t("button",{staticClass:"wp-mail-smtp-button wp-mail-smtp-button-main",attrs:{type:"button",name:"start_troubleshooting"},domProps:{textContent:e._s(e.text_start_troubleshooting)},on:{click:function(t){return t.preventDefault(),e.handleTroubleshooting.apply(null,arguments)}}}),t("button",{staticClass:"wp-mail-smtp-button",attrs:{type:"button",name:"finish_setup"},domProps:{textContent:e._s(e.text_finish)},on:{click:function(t){return t.preventDefault(),e.handleFinish.apply(null,arguments)}}})])])},Bt=[],Tt={name:"WizardStepConfigurationFailure",components:{ContentHeader:f,TheWizardStepCounter:j},data(){return{text_header_title:(0,l.__)("Whoops, looks like things arenāt configured properly.","wp-mail-smtp"),text_header_subtitle:(0,l.__)("We just tried to send a test email, but something prevented that from working. To see more details about the issue we detected, as well as our suggestions to fix it, please start troubleshooting.","wp-mail-smtp"),text_start_troubleshooting:(0,l.__)("Start Troubleshooting","wp-mail-smtp"),text_send_feedback:(0,l.__)("Send us Feedback","wp-mail-smtp"),text_finish:(0,l.__)("Finish Setup","wp-mail-smtp")}},methods:{handleTroubleshooting(){return window.location=`${this.$wpms.email_test_tab_url}&auto-start=1`},handleFinish(){return window.location=this.$wpms.exit_url}}},It=Tt,Dt=(0,d.A)(It,Ft,Bt,!1,null,null,null),Ot=Dt.exports,zt=function(){var e=this,t=e._self._c;return t("div",{staticClass:"wp-mail-smtp-setup-wizard-step-configure-mailer-settings wp-mail-smtp-setup-wizard-step-configure-mailer-settings-smtp"},[t("p",{staticClass:"mailer-description",domProps:{innerHTML:e._s(e.description)}}),t("div",{staticClass:"wp-mail-smtp-setup-wizard-form"},[t("settings-input-text",{attrs:{name:"host",constant:"WPMS_SMTP_HOST",label:e.text_host_label,is_error:e.field_errors.includes("host")},on:{is_error_update:function(t){return e.removeFieldError("host")}},model:{value:e.host,callback:function(t){e.host=t},expression:"host"}}),t("settings-input-radio",{attrs:{name:"encryption",constant:"WPMS_SSL",label:e.text_encryption_label,options:e.encryptionOptions,description:e.text_encryption_description},on:{input:e.encryptionChanged},model:{value:e.encryption,callback:function(t){e.encryption=t},expression:"encryption"}}),t("settings-input-number",{attrs:{name:"port",constant:"WPMS_SMTP_PORT",label:e.text_port_label,is_error:e.field_errors.includes("port")},on:{is_error_update:function(t){return e.removeFieldError("port")}},model:{value:e.port,callback:function(t){e.port=t},expression:"port"}}),t("settings-input-switch",{directives:[{name:"show",rawName:"v-show",value:e.show_autotls,expression:"show_autotls"}],attrs:{name:"autotls",constant:"WPMS_SMTP_AUTOTLS",title:e.text_autotls_title,label:e.text_autotls_label,description:e.text_autotls_description},model:{value:e.autotls,callback:function(t){e.autotls=t},expression:"autotls"}}),t("div",{staticClass:"wp-mail-smtp-separator wp-mail-smtp-separator-big-margin"}),t("settings-input-switch",{attrs:{name:"auth",constant:"WPMS_SMTP_AUTH",title:e.text_auth_title,label:e.text_auth_label},model:{value:e.auth,callback:function(t){e.auth=t},expression:"auth"}}),t("settings-input-text",{directives:[{name:"show",rawName:"v-show",value:e.auth,expression:"auth"}],attrs:{name:"user",constant:"WPMS_SMTP_USER",label:e.text_user_label,is_error:e.field_errors.includes("user")},on:{is_error_update:function(t){return e.removeFieldError("user")}},model:{value:e.user,callback:function(t){e.user=t},expression:"user"}}),t("settings-input-text",{directives:[{name:"show",rawName:"v-show",value:e.auth,expression:"auth"}],attrs:{name:"pass",constant:"WPMS_SMTP_PASS",type:"password",label:e.text_pass_label,is_error:e.field_errors.includes("pass")},on:{is_error_update:function(t){return e.removeFieldError("pass")}},model:{value:e.pass,callback:function(t){e.pass=t},expression:"pass"}}),t("div",{staticClass:"wp-mail-smtp-separator wp-mail-smtp-separator-big-margin"}),t("settings-input-text",{attrs:{name:"from_name",constant:"WPMS_MAIL_FROM_NAME",label:e.text_from_name_label,description:e.text_from_name_description},model:{value:e.from_name,callback:function(t){e.from_name=t},expression:"from_name"}}),t("settings-input-switch",{attrs:{classname:"sub_setting",name:"from_name_force",constant:"WPMS_MAIL_FROM_NAME_FORCE",title:e.text_force_from_name_title,label:e.text_force_from_name_label},model:{value:e.from_name_force,callback:function(t){e.from_name_force=t},expression:"from_name_force"}}),t("settings-input-text",{attrs:{name:"from_email",type:"email",constant:"WPMS_MAIL_FROM",label:e.text_from_email_label,description:e.text_from_email_description,is_error:e.field_errors.includes("from_email")},on:{is_error_update:function(t){return e.removeFieldError("from_email")},error_detected:t=>e.errorDetected(t,"from_email")},model:{value:e.from_email,callback:function(t){e.from_email=t},expression:"from_email"}}),t("settings-input-switch",{attrs:{classname:"sub_setting",name:"from_email_force",constant:"WPMS_MAIL_FROM_FORCE",title:e.text_force_from_email_title,label:e.text_force_from_email_label},model:{value:e.from_email_force,callback:function(t){e.from_email_force=t},expression:"from_email_force"}})],1)])},Lt=[],Rt=function(){var e=this,t=e._self._c;return t("div",{staticClass:"settings-input-radio"},[e.label?t("span",{staticClass:"settings-input-label-container"},[t("span",{staticClass:"label"},[e._v(e._s(e.label))])]):e._e(),t("div",{staticClass:"settings-input-radio-container"},e._l(e.options,(function(i){return t("label",{key:i.value,class:e.labelClass(i.value),attrs:{for:"wp-mail-smtp-settings-radio-"+e.name+"["+i.value+"]"}},[t("input",{directives:[{name:"model",rawName:"v-model",value:e.selected,expression:"selected"}],attrs:{id:"wp-mail-smtp-settings-radio-"+e.name+"["+i.value+"]",type:"radio",name:e.name,autocomplete:"off",readonly:e.disabled,disabled:e.is_constant_set},domProps:{value:i.value,checked:e.isChecked(i.value),checked:e._q(e.selected,i.value)},on:{change:[function(t){e.selected=i.value},e.updateSetting]}}),t("span",{class:e.titleClass(i.value)}),t("span",{staticClass:"input-label"},[e._v(e._s(i.label))])])})),0),e.description?t("p",{staticClass:"description",domProps:{innerHTML:e._s(e.description)}}):e._e(),e.is_constant_set?t("p",{staticClass:"description description--constant",domProps:{innerHTML:e._s(e.text_constant)}}):e._e()])},Wt=[],Nt={name:"SettingsInputRadio",props:{options:Array,label:String,name:String,value:String,description:String,constant:String,disabled:Boolean},data(){return{has_error:!1}},computed:{selected:{get(){return this.value},set(e){this.$emit("input",e)}},is_constant_set:function(){return this.$wpms.defined_constants.includes(this.constant)},text_constant:function(){return(0,l.__)("This setting is already configured with the WP Mail SMTP constant. To change it, please edit or remove the "+this.constant+" constant in your wp-config.php file.","wp-mail-smtp")}},methods:{updateSetting:function(){if(this.disabled)return!1},titleClass(e){let t="wp-mail-smtp-styled-radio";return this.isChecked(e)&&(t+=" wp-mail-smtp-styled-radio-checked"),this.is_constant_set&&(t+=" wp-mail-smtp-styled-radio-disabled"),t},labelClass(e){let t="";return this.isChecked(e)&&(t+=" wp-mail-smtp-styled-radio-label-checked"),this.is_constant_set&&(t+=" wp-mail-smtp-styled-radio-label-disabled"),t},isChecked(e){return e===this.selected}}},Ut=Nt,Qt=(0,d.A)(Ut,Rt,Wt,!1,null,null,null),Zt=Qt.exports,Gt=function(){var e=this,t=e._self._c;return t("div",{staticClass:"settings-input-number",class:{"settings-input-number-error":e.field_error}},[t("label",{staticClass:"settings-input-label-container",attrs:{for:e.id}},[e.label?t("span",{staticClass:"label"},[e._v(e._s(e.label))]):e._e(),e.tooltip?t("settings-info-tooltip",{attrs:{content:e.tooltip}}):e._e()],1),t("input",{directives:[{name:"model",rawName:"v-model",value:e.currentValue,expression:"currentValue"}],attrs:{id:e.id,type:"number",name:e.name,placeholder:e.placeholder,min:e.min,max:e.max,step:e.step,readonly:e.disabled,disabled:e.is_constant_set},domProps:{value:e.currentValue},on:{change:e.inputUpdate,input:function(t){t.target.composing||(e.currentValue=t.target.value)}}}),e.has_error?t("p",{staticClass:"error"},[t("inline-svg",{staticClass:"icon",attrs:{src:i(617),width:"16"}}),t("span",{domProps:{innerHTML:e._s(e.has_error)}})],1):e._e(),e.description?t("p",{staticClass:"description"},[e._v(" "+e._s(e.description)+" ")]):e._e(),e.is_constant_set?t("p",{staticClass:"description description--constant",domProps:{innerHTML:e._s(e.text_constant)}}):e._e()])},Yt=[],Ht={name:"SettingsInputNumber",components:{SettingsInfoTooltip:Le},props:{name:String,value:[Number,String],label:String,description:String,constant:String,placeholder:String,type:{type:String,default:"text"},tooltip:String,default_value:String,min:Number,max:Number,disabled:Boolean,step:{type:Number,default:1},round:{type:Boolean,default:!1},is_error:Boolean},data(){return{has_error:!1,id:"input-"+this.name,text_error_value:(0,l.nv)((0,l.__)("Please enter a value between %1$s and %2$s","wp-mail-smtp"),""+this.min+"",""+this.max+""),text_error_round:(0,l.__)("Value has to be a round number","wp-mail-smtp")}},computed:{currentValue:{get(){return this.value},set(e){this.$emit("is_error_update",!1),this.$emit("input",parseInt(e,10))}},field_error:{get(){return this.is_error},set(e){this.$emit("is_error_update",e)}},is_constant_set:function(){return this.$wpms.defined_constants.includes(this.constant)},text_constant:function(){return(0,l.__)("This setting is already configured with the WP Mail SMTP constant. To change it, please edit or remove the "+this.constant+" constant in your wp-config.php file.","wp-mail-smtp")}},methods:{inputUpdate:function(e){if(this.disabled)return!1;this.has_error=!1;const t=parseFloat(e.target.value);return this.round&&t%1!==0?(this.has_error=this.text_error_round,!1):t>this.max||t-1:e.currentValue},on:{change:[function(t){var i=e.currentValue,s=t.target,a=!!s.checked;if(Array.isArray(i)){var n=null,r=e._i(i,n);s.checked?r<0&&(e.currentValue=i.concat([n])):r>-1&&(e.currentValue=i.slice(0,r).concat(i.slice(r+1)))}else e.currentValue=a},e.inputUpdate],click:e.inputClicked}}),t("span",{class:{"toggle-switch":!0,"toggle-switch-with-label":e.label}}),e.label?t("span",{staticClass:"label-description",domProps:{innerHTML:e._s(e.label)}}):e._e()])])])},jt=[],Xt={name:"SettingsInputSwitch",components:{SettingsInfoTooltip:Le},props:{name:String,value:Boolean,title:String,label:String,description:String,constant:String,tooltip:String,classname:String,disabled:Boolean,show_pro:Boolean},data(){return{has_error:!1,id:"input-"+this.name}},computed:{currentValue:{get(){return this.value},set(e){this.$emit("input",!!e)}},is_constant_set:function(){return this.$wpms.defined_constants.includes(this.constant)},text_constant:function(){return(0,l.__)("This setting is already configured with the WP Mail SMTP constant. To change it, please edit or remove the "+this.constant+" constant in your wp-config.php file.","wp-mail-smtp")}},methods:{inputUpdate:function(){if(this.disabled)return!1},inputClicked(e){this.$emit("clicked",e)}}},$t=Xt,ei=(0,d.A)($t,Jt,jt,!1,null,null,null),ti=ei.exports,ii={name:"WizardStepConfigureMailerSmtp",components:{SettingsInputText:Ue,SettingsInputRadio:Zt,SettingsInputNumber:qt,SettingsInputSwitch:ti},data(){return{mailer:"smtp",text_host_label:(0,l.__)("SMTP Host","wp-mail-smtp"),text_encryption_label:(0,l.__)("Encryption","wp-mail-smtp"),text_port_label:(0,l.__)("SMTP Port","wp-mail-smtp"),text_autotls_title:(0,l.__)("Auto TLS","wp-mail-smtp"),text_autotls_label:(0,l.__)("Enable Auto TLS","wp-mail-smtp"),text_autotls_description:(0,l.__)("By default, TLS encryption is automatically used if the server supports it (recommended). In some cases, due to server misconfigurations, this can cause issues and may need to be disabled.","wp-mail-smtp"),text_auth_title:(0,l.__)("Authentication","wp-mail-smtp"),text_auth_label:(0,l.__)("Enable Authentication","wp-mail-smtp"),text_user_label:(0,l.__)("SMTP Username","wp-mail-smtp"),text_pass_label:(0,l.__)("SMTP Password","wp-mail-smtp"),text_from_name_label:(0,l.__)("From Name","wp-mail-smtp"),text_force_from_name_title:(0,l.__)("Force From Name","wp-mail-smtp"),text_from_email_label:(0,l.__)("From Email","wp-mail-smtp"),text_force_from_email_title:(0,l.__)("Force From Email","wp-mail-smtp"),text_from_name_description:(0,l.__)("The name that emails are sent from.","wp-mail-smtp"),text_from_email_description:(0,l.__)("The email address that emails are sent from.","wp-mail-smtp"),text_encryption_description:(0,l.__)("For most servers TLS is the recommended option. If your SMTP provider offers both SSL and TLS options, we recommend using TLS.","wp-mail-smtp"),text_force_from_name_label:(0,l.__)("If enabled, the From Name setting above will be used for all emails, ignoring values set by other plugins.","wp-mail-smtp"),text_force_from_email_label:(0,l.__)("If enabled, the From Email setting above will be used for all emails, ignoring values set by other plugins.","wp-mail-smtp"),description:this.$wpms.mailer_options.smtp.description,encryptionOptions:[{label:(0,l.__)("None","wp-mail-smtp"),value:"none",default_port:25},{label:(0,l.__)("SSL","wp-mail-smtp"),value:"ssl",default_port:465},{label:(0,l.__)("TLS","wp-mail-smtp"),value:"tls",default_port:587}],show_autotls:!0,show_user_and_pass:!0,field_errors:[]}},computed:{...(0,_e.YP)("$_settings",["settings.smtp.host","settings.smtp.auth","settings.smtp.port","settings.smtp.encryption","settings.smtp.user","settings.smtp.pass","settings.smtp.autotls","settings.mail.from_email","settings.mail.from_name","settings.mail.from_email_force","settings.mail.from_name_force"])},watch:{encryption:function(e){this.show_autotls="tls"!==e}},methods:{getEncryptionDefaultPort(e){return this.encryptionOptions.find((t=>t.value===e)).default_port},encryptionChanged(e){this.port=this.getEncryptionDefaultPort(e)},areRequiredFieldsValid(){return""===this.host&&this.field_errors.push("host"),(""===this.port||isNaN(this.port))&&this.field_errors.push("port"),this.auth&&(""===this.user&&this.field_errors.push("user"),""===this.pass&&this.field_errors.push("pass")),""===this.from_email&&this.field_errors.push("from_email"),0===this.field_errors.length},removeFieldError(e){this.field_errors=this.field_errors.filter((t=>t!==e))},errorDetected(e,t){this.field_errors.push(t)}},mounted(){"tls"===this.encryption&&(this.show_autotls=!1)}},si=ii,ai=(0,d.A)(si,zt,Lt,!1,null,null,null),ni=ai.exports,ri=function(){var e=this,t=e._self._c;return t("div",{staticClass:"wp-mail-smtp-setup-wizard-step-configure-mailer-settings wp-mail-smtp-setup-wizard-step-configure-mailer-settings-sendlayer"},[t("p",{staticClass:"mailer-description",domProps:{innerHTML:e._s(e.description)}}),t("p",{staticClass:"mailer-description mailer-description-links"},[t("a",{staticClass:"wp-mail-smtp-button wp-mail-smtp-button-small wp-mail-smtp-button-secondary",attrs:{href:e.get_started_button_url,target:"_blank",rel:"noopener noreferrer"}},[t("span",{staticClass:"text-with-arrow text-with-arrow-right"},[e._v(" "+e._s(e.text_get_started_button)),t("inline-svg",{staticClass:"icon",attrs:{src:i(953),width:"16",height:"23"}})],1)]),t("a",{staticClass:"wp-mail-smtp-link wp-mail-smtp-link-docs",attrs:{href:e.documentation_link_url,target:"_blank",rel:"noopener noreferrer"}},[e._v(e._s(e.text_documentation_link))])]),t("div",{staticClass:"wp-mail-smtp-setup-wizard-form"},[t("settings-input-text",{attrs:{name:"api_key",type:"password",constant:"WPMS_SENDLAYER_API_KEY",label:e.text_api_key_label,description:e.text_api_key_description,is_error:e.field_errors.includes("api_key")},on:{is_error_update:function(t){return e.removeFieldError("api_key")}},model:{value:e.api_key,callback:function(t){e.api_key=t},expression:"api_key"}}),t("settings-input-text",{attrs:{name:"from_name",constant:"WPMS_MAIL_FROM_NAME",label:e.text_from_name_label,description:e.text_from_name_description},model:{value:e.from_name,callback:function(t){e.from_name=t},expression:"from_name"}}),t("settings-input-switch",{attrs:{classname:"sub_setting",name:"from_name_force",constant:"WPMS_MAIL_FROM_NAME_FORCE",title:e.text_force_from_name_title,label:e.text_force_from_name_label},model:{value:e.from_name_force,callback:function(t){e.from_name_force=t},expression:"from_name_force"}}),t("settings-input-text",{attrs:{name:"from_email",type:"email",constant:"WPMS_MAIL_FROM",label:e.text_from_email_label,description:e.text_from_email_description,is_error:e.field_errors.includes("from_email")},on:{is_error_update:function(t){return e.removeFieldError("from_email")},error_detected:t=>e.errorDetected(t,"from_email")},model:{value:e.from_email,callback:function(t){e.from_email=t},expression:"from_email"}}),t("settings-input-switch",{attrs:{classname:"sub_setting",name:"from_email_force",constant:"WPMS_MAIL_FROM_FORCE",title:e.text_force_from_email_title,label:e.text_force_from_email_label},model:{value:e.from_email_force,callback:function(t){e.from_email_force=t},expression:"from_email_force"}})],1)])},oi=[],li={name:"WizardStepConfigureMailerSendlayer",components:{SettingsInputText:Ue,SettingsInputSwitch:ti},data(){return{mailer:"sendlayer",text_api_key_label:(0,l.__)("API Key","wp-mail-smtp"),text_api_key_description:(0,l.nv)((0,l.__)("%1$sFollow this link%2$s to get an API Key for SendLayer.","wp-mail-smtp"),'',""),text_from_name_label:(0,l.__)("From Name","wp-mail-smtp"),text_force_from_name_title:(0,l.__)("Force From Name","wp-mail-smtp"),text_from_email_label:(0,l.__)("From Email","wp-mail-smtp"),text_force_from_email_title:(0,l.__)("Force From Email","wp-mail-smtp"),text_force_from_name_label:(0,l.__)("If enabled, the From Name setting above will be used for all emails, ignoring values set by other plugins.","wp-mail-smtp"),text_force_from_email_label:(0,l.__)("If enabled, the From Email setting above will be used for all emails, ignoring values set by other plugins.","wp-mail-smtp"),text_from_name_description:(0,l.__)("The name that emails are sent from.","wp-mail-smtp"),text_from_email_description:(0,l.__)("The email address that emails are sent from.","wp-mail-smtp"),text_get_started_button:(0,l.__)("Get Started with SendLayer","wp-mail-smtp"),text_documentation_link:(0,l.__)("Read how to set up SendLayer","wp-mail-smtp"),description:this.$wpms.mailer_options.sendlayer.description.substr(0,this.$wpms.mailer_options.sendlayer.description.lastIndexOf("
")),get_started_button_url:this.$getUTMUrl("https://sendlayer.com/wp-mail-smtp/",{source:"wpmailsmtpplugin",medium:"WordPress",content:"Setup Wizard - Mailer Button"}),documentation_link_url:this.$getUTMUrl("https://wpmailsmtp.com/docs/how-to-set-up-the-sendlayer-mailer-in-wp-mail-smtp/",{content:"Read how to set up SendLayer"}),field_errors:[]}},computed:{...(0,_e.YP)("$_settings",["settings.sendlayer.api_key","settings.mail.from_email","settings.mail.from_name","settings.mail.from_email_force","settings.mail.from_name_force"])},methods:{areRequiredFieldsValid(){return""===this.api_key&&this.field_errors.push("api_key"),""===this.from_email&&this.field_errors.push("from_email"),0===this.field_errors.length},removeFieldError(e){this.field_errors=this.field_errors.filter((t=>t!==e))},errorDetected(e,t){this.field_errors.push(t)}}},mi=li,pi=(0,d.A)(mi,ri,oi,!1,null,null,null),_i=pi.exports,ci=function(){var e=this,t=e._self._c;return t("div",{staticClass:"wp-mail-smtp-setup-wizard-step-configure-mailer-settings wp-mail-smtp-setup-wizard-step-configure-mailer-settings-smtpcom"},[t("p",{staticClass:"mailer-description",domProps:{innerHTML:e._s(e.description)}}),t("p",{staticClass:"mailer-description mailer-description-links"},[t("a",{staticClass:"wp-mail-smtp-button wp-mail-smtp-button-small wp-mail-smtp-button-secondary",attrs:{href:"https://wpmailsmtp.com/go/smtp/",target:"_blank",rel:"noopener noreferrer"}},[t("span",{staticClass:"text-with-arrow text-with-arrow-right"},[e._v(" "+e._s(e.text_get_started_button)),t("inline-svg",{staticClass:"icon",attrs:{src:i(953),width:"16",height:"23"}})],1)]),t("a",{staticClass:"wp-mail-smtp-link wp-mail-smtp-link-docs",attrs:{href:e.documentation_link_url,target:"_blank",rel:"noopener noreferrer"}},[e._v(e._s(e.text_documentation_link))]),t("span",{directives:[{name:"tooltip",rawName:"v-tooltip",value:e.disclosure_tooltip_data,expression:"disclosure_tooltip_data"}],staticClass:"mailer-offer-link-disclosure"},[e._v(e._s(e.text_disclosure))])]),t("div",{staticClass:"wp-mail-smtp-setup-wizard-form"},[t("settings-input-text",{attrs:{name:"api_key",type:"password",constant:"WPMS_SMTPCOM_API_KEY",label:e.text_api_key_label,description:e.text_api_key_description,is_error:e.field_errors.includes("api_key")},on:{is_error_update:function(t){return e.removeFieldError("api_key")}},model:{value:e.api_key,callback:function(t){e.api_key=t},expression:"api_key"}}),t("settings-input-text",{attrs:{name:"channel",constant:"WPMS_SMTPCOM_CHANNEL",label:e.text_channel_label,description:e.text_channel_description,is_error:e.field_errors.includes("channel")},on:{is_error_update:function(t){return e.removeFieldError("channel")}},model:{value:e.channel,callback:function(t){e.channel=t},expression:"channel"}}),t("settings-input-text",{attrs:{name:"from_name",constant:"WPMS_MAIL_FROM_NAME",label:e.text_from_name_label,description:e.text_from_name_description},model:{value:e.from_name,callback:function(t){e.from_name=t},expression:"from_name"}}),t("settings-input-switch",{attrs:{classname:"sub_setting",name:"from_name_force",constant:"WPMS_MAIL_FROM_NAME_FORCE",title:e.text_force_from_name_title,label:e.text_force_from_name_label},model:{value:e.from_name_force,callback:function(t){e.from_name_force=t},expression:"from_name_force"}}),t("settings-input-text",{attrs:{name:"from_email",type:"email",constant:"WPMS_MAIL_FROM",label:e.text_from_email_label,description:e.text_from_email_description,is_error:e.field_errors.includes("from_email")},on:{is_error_update:function(t){return e.removeFieldError("from_email")},error_detected:t=>e.errorDetected(t,"from_email")},model:{value:e.from_email,callback:function(t){e.from_email=t},expression:"from_email"}}),t("settings-input-switch",{attrs:{classname:"sub_setting",name:"from_email_force",constant:"WPMS_MAIL_FROM_FORCE",title:e.text_force_from_email_title,label:e.text_force_from_email_label},model:{value:e.from_email_force,callback:function(t){e.from_email_force=t},expression:"from_email_force"}})],1)])},di=[],ui={name:"WizardStepConfigureMailerSmtpCom",components:{SettingsInputText:Ue,SettingsInputSwitch:ti},data(){return{mailer:"smtpcom",text_api_key_label:(0,l.__)("API Key","wp-mail-smtp"),text_channel_label:(0,l.__)("Sender Name","wp-mail-smtp"),text_api_key_description:(0,l.nv)((0,l.__)("%1$sFollow this link%2$s to get an API Key for SMTP.com.","wp-mail-smtp"),'',""),text_channel_description:(0,l.nv)((0,l.__)("%1$sFollow this link%2$s to get a Sender Name for SMTP.com.","wp-mail-smtp"),'',""),text_from_name_label:(0,l.__)("From Name","wp-mail-smtp"),text_force_from_name_title:(0,l.__)("Force From Name","wp-mail-smtp"),text_from_email_label:(0,l.__)("From Email","wp-mail-smtp"),text_force_from_email_title:(0,l.__)("Force From Email","wp-mail-smtp"),text_force_from_name_label:(0,l.__)("If enabled, the From Name setting above will be used for all emails, ignoring values set by other plugins.","wp-mail-smtp"),text_force_from_email_label:(0,l.__)("If enabled, the From Email setting above will be used for all emails, ignoring values set by other plugins.","wp-mail-smtp"),text_from_name_description:(0,l.__)("The name that emails are sent from.","wp-mail-smtp"),text_from_email_description:(0,l.__)("The email address that emails are sent from.","wp-mail-smtp"),text_get_started_button:(0,l.__)("Get Started with SMTP.com","wp-mail-smtp"),text_documentation_link:(0,l.__)("Read how to set up SMTP.com","wp-mail-smtp"),text_disclosure:(0,l.__)("Transparency and Disclosure","wp-mail-smtp"),disclosure_tooltip_data:{content:(0,l.__)("We believe in full transparency. The SMTP.com links above are tracking links as part of our partnership with SMTP (j2 Global). We can recommend just about any SMTP service, but we only recommend products that we believe will add value to our users.","wp-mail-smtp"),autoHide:!0,trigger:"hover"},description:this.$wpms.mailer_options.smtpcom.description.substr(0,this.$wpms.mailer_options.smtpcom.description.lastIndexOf("
")),documentation_link_url:this.$getUTMUrl("https://wpmailsmtp.com/docs/how-to-set-up-the-smtp-com-mailer-in-wp-mail-smtp",{content:"Read how to set up SMTP.com"}),field_errors:[]}},computed:{...(0,_e.YP)("$_settings",["settings.smtpcom.api_key","settings.smtpcom.channel","settings.mail.from_email","settings.mail.from_name","settings.mail.from_email_force","settings.mail.from_name_force"])},methods:{areRequiredFieldsValid(){return""===this.api_key&&this.field_errors.push("api_key"),""===this.channel&&this.field_errors.push("channel"),""===this.from_email&&this.field_errors.push("from_email"),0===this.field_errors.length},removeFieldError(e){this.field_errors=this.field_errors.filter((t=>t!==e))},errorDetected(e,t){this.field_errors.push(t)}}},fi=ui,hi=(0,d.A)(fi,ci,di,!1,null,null,null),gi=hi.exports,wi=function(){var e=this,t=e._self._c;return t("div",{staticClass:"wp-mail-smtp-setup-wizard-step-configure-mailer-settings wp-mail-smtp-setup-wizard-step-configure-mailer-settings-sendinblue"},[t("p",{staticClass:"mailer-description",domProps:{innerHTML:e._s(e.description)}}),t("p",{staticClass:"mailer-description mailer-description-links"},[t("a",{staticClass:"wp-mail-smtp-button wp-mail-smtp-button-small wp-mail-smtp-button-secondary",attrs:{href:"https://wpmailsmtp.com/go/sendinblue/",target:"_blank",rel:"noopener noreferrer"}},[t("span",{staticClass:"text-with-arrow text-with-arrow-right"},[e._v(" "+e._s(e.text_get_started_button)),t("inline-svg",{staticClass:"icon",attrs:{src:i(953),width:"16",height:"23"}})],1)]),t("a",{staticClass:"wp-mail-smtp-link wp-mail-smtp-link-docs",attrs:{href:e.documentation_link_url,target:"_blank",rel:"noopener noreferrer"}},[e._v(e._s(e.text_documentation_link))]),t("span",{directives:[{name:"tooltip",rawName:"v-tooltip",value:e.disclosure_tooltip_data,expression:"disclosure_tooltip_data"}],staticClass:"mailer-offer-link-disclosure"},[e._v(e._s(e.text_disclosure))])]),t("div",{staticClass:"wp-mail-smtp-setup-wizard-form"},[t("settings-input-text",{attrs:{name:"api_key",type:"password",constant:"WPMS_SENDINBLUE_API_KEY",label:e.text_api_key_label,description:e.text_api_key_description,is_error:e.field_errors.includes("api_key")},on:{is_error_update:function(t){return e.removeFieldError("api_key")}},model:{value:e.api_key,callback:function(t){e.api_key=t},expression:"api_key"}}),t("settings-input-text",{attrs:{name:"domain",constant:"WPMS_SENDINBLUE_DOMAIN",label:e.text_domain_label,description:e.text_domain_description},model:{value:e.domain,callback:function(t){e.domain=t},expression:"domain"}}),t("settings-input-text",{attrs:{name:"from_name",constant:"WPMS_MAIL_FROM_NAME",label:e.text_from_name_label,description:e.text_from_name_description},model:{value:e.from_name,callback:function(t){e.from_name=t},expression:"from_name"}}),t("settings-input-switch",{attrs:{classname:"sub_setting",name:"from_name_force",constant:"WPMS_MAIL_FROM_NAME_FORCE",title:e.text_force_from_name_title,label:e.text_force_from_name_label},model:{value:e.from_name_force,callback:function(t){e.from_name_force=t},expression:"from_name_force"}}),t("settings-input-text",{attrs:{name:"from_email",type:"email",constant:"WPMS_MAIL_FROM",label:e.text_from_email_label,description:e.text_from_email_description,is_error:e.field_errors.includes("from_email")},on:{is_error_update:function(t){return e.removeFieldError("from_email")},error_detected:t=>e.errorDetected(t,"from_email")},model:{value:e.from_email,callback:function(t){e.from_email=t},expression:"from_email"}}),t("settings-input-switch",{attrs:{classname:"sub_setting",name:"from_email_force",constant:"WPMS_MAIL_FROM_FORCE",title:e.text_force_from_email_title,label:e.text_force_from_email_label},model:{value:e.from_email_force,callback:function(t){e.from_email_force=t},expression:"from_email_force"}})],1)])},Ai=[],bi={name:"WizardStepConfigureMailerSendinblue",components:{SettingsInputText:Ue,SettingsInputSwitch:ti},data(){return{mailer:"sendinblue",text_api_key_label:(0,l.__)("API Key","wp-mail-smtp"),text_domain_label:(0,l.__)("Sending Domain","wp-mail-smtp"),text_api_key_description:(0,l.nv)((0,l.__)("%1$sFollow this link%2$s to get an API Key for Brevo.","wp-mail-smtp"),'',""),text_domain_description:(0,l.nv)((0,l.__)("Please input the sending domain/subdomain you configured in your Brevo dashboard. More information can be found in our %1$sBrevo documentation%2$s","wp-mail-smtp"),'',""),text_from_name_label:(0,l.__)("From Name","wp-mail-smtp"),text_force_from_name_title:(0,l.__)("Force From Name","wp-mail-smtp"),text_from_email_label:(0,l.__)("From Email","wp-mail-smtp"),text_force_from_email_title:(0,l.__)("Force From Email","wp-mail-smtp"),text_force_from_name_label:(0,l.__)("If enabled, the From Name setting above will be used for all emails, ignoring values set by other plugins.","wp-mail-smtp"),text_force_from_email_label:(0,l.__)("If enabled, the From Email setting above will be used for all emails, ignoring values set by other plugins.","wp-mail-smtp"),text_from_name_description:(0,l.__)("The name that emails are sent from.","wp-mail-smtp"),text_from_email_description:(0,l.__)("The email address that emails are sent from.","wp-mail-smtp"),text_get_started_button:(0,l.__)("Get Started with Brevo","wp-mail-smtp"),text_documentation_link:(0,l.__)("Read how to set up Brevo","wp-mail-smtp"),text_disclosure:(0,l.__)("Transparency and Disclosure","wp-mail-smtp"),disclosure_tooltip_data:{content:(0,l.__)("We believe in full transparency. The Brevo links above are tracking links as part of our partnership with Brevo. We can recommend just about any SMTP service, but we only recommend products that we believe will add value to our users.","wp-mail-smtp"),autoHide:!0,trigger:"hover"},description:this.$wpms.mailer_options.sendinblue.description.substr(0,this.$wpms.mailer_options.sendinblue.description.lastIndexOf("
")),documentation_link_url:this.$getUTMUrl("https://wpmailsmtp.com/docs/how-to-set-up-the-sendinblue-mailer-in-wp-mail-smtp",{content:"Read how to set up Brevo"}),field_errors:[]}},computed:{...(0,_e.YP)("$_settings",["settings.sendinblue.api_key","settings.sendinblue.domain","settings.mail.from_email","settings.mail.from_name","settings.mail.from_email_force","settings.mail.from_name_force"])},methods:{areRequiredFieldsValid(){return""===this.api_key&&this.field_errors.push("api_key"),""===this.from_email&&this.field_errors.push("from_email"),0===this.field_errors.length},removeFieldError(e){this.field_errors=this.field_errors.filter((t=>t!==e))},errorDetected(e,t){this.field_errors.push(t)}}},vi=bi,xi=(0,d.A)(vi,wi,Ai,!1,null,null,null),ki=xi.exports,yi=function(){var e=this,t=e._self._c;return t("div",{staticClass:"wp-mail-smtp-setup-wizard-step-configure-mailer-settings wp-mail-smtp-setup-wizard-step-configure-mailer-settings-mailersend"},[t("p",{staticClass:"mailer-description",domProps:{innerHTML:e._s(e.description)}}),t("p",{staticClass:"mailer-description mailer-description-links"},[t("a",{staticClass:"wp-mail-smtp-link",attrs:{href:e.documentation_link_url,target:"_blank",rel:"noopener noreferrer"}},[e._v(e._s(e.text_documentation_link))])]),t("div",{staticClass:"wp-mail-smtp-setup-wizard-form"},[t("settings-input-text",{attrs:{name:"api_key",type:"password",constant:"WPMS_MAILERSEND_API_KEY",label:e.text_api_key_label,description:e.text_api_key_description,is_error:e.field_errors.includes("api_key")},on:{is_error_update:function(t){return e.removeFieldError("api_key")}},model:{value:e.api_key,callback:function(t){e.api_key=t},expression:"api_key"}}),t("settings-input-switch",{attrs:{name:"has_pro_plan",constant:"WPMS_MAILERSEND_HAS_PRO_PLAN",title:e.text_pro_plan_title,label:e.text_pro_plan_label},model:{value:e.has_pro_plan,callback:function(t){e.has_pro_plan=t},expression:"has_pro_plan"}}),t("settings-input-text",{attrs:{name:"from_name",constant:"WPMS_MAIL_FROM_NAME",label:e.text_from_name_label,description:e.text_from_name_description},model:{value:e.from_name,callback:function(t){e.from_name=t},expression:"from_name"}}),t("settings-input-switch",{attrs:{classname:"sub_setting",name:"from_name_force",constant:"WPMS_MAIL_FROM_NAME_FORCE",title:e.text_force_from_name_title,label:e.text_force_from_name_label},model:{value:e.from_name_force,callback:function(t){e.from_name_force=t},expression:"from_name_force"}}),t("settings-input-text",{attrs:{name:"from_email",type:"email",constant:"WPMS_MAIL_FROM",label:e.text_from_email_label,description:e.text_from_email_description,is_error:e.field_errors.includes("from_email")},on:{is_error_update:function(t){return e.removeFieldError("from_email")},error_detected:t=>e.errorDetected(t,"from_email")},model:{value:e.from_email,callback:function(t){e.from_email=t},expression:"from_email"}}),t("settings-input-switch",{attrs:{classname:"sub_setting",name:"from_email_force",constant:"WPMS_MAIL_FROM_FORCE",title:e.text_force_from_email_title,label:e.text_force_from_email_label},model:{value:e.from_email_force,callback:function(t){e.from_email_force=t},expression:"from_email_force"}})],1)])},Ci=[],Si={name:"WizardStepConfigureMailerMailerSend",components:{SettingsInputText:Ue,SettingsInputSwitch:ti},data(){return{mailer:"mailersend",text_api_key_label:(0,l.__)("API Key","wp-mail-smtp"),text_pro_plan_title:(0,l.__)("Pro Plan Features","wp-mail-smtp"),text_api_key_description:(0,l.nv)((0,l.__)("%1$sFollow this link%2$s to get an API Key for MailerSend.","wp-mail-smtp"),'',""),text_pro_plan_label:(0,l.__)("Enable if you have a Pro plan or higher to use advanced features like custom headers.","wp-mail-smtp"),text_from_name_label:(0,l.__)("From Name","wp-mail-smtp"),text_force_from_name_title:(0,l.__)("Force From Name","wp-mail-smtp"),text_from_email_label:(0,l.__)("From Email","wp-mail-smtp"),text_force_from_email_title:(0,l.__)("Force From Email","wp-mail-smtp"),text_force_from_name_label:(0,l.__)("If enabled, the From Name setting above will be used for all emails, ignoring values set by other plugins.","wp-mail-smtp"),text_force_from_email_label:(0,l.__)("If enabled, the From Email setting above will be used for all emails, ignoring values set by other plugins.","wp-mail-smtp"),text_from_name_description:(0,l.__)("The name that emails are sent from.","wp-mail-smtp"),text_from_email_description:(0,l.__)("The email address that emails are sent from.","wp-mail-smtp"),text_documentation_link:(0,l.__)("Read how to set up MailerSend","wp-mail-smtp"),description:this.$wpms.mailer_options.mailersend.description.substr(0,this.$wpms.mailer_options.mailersend.description.indexOf(" ")),documentation_link_url:this.$getUTMUrl("https://wpmailsmtp.com/docs/how-to-set-up-the-mailersend-mailer-in-wp-mail-smtp/",{content:"Read how to set up MailerSend"}),field_errors:[]}},computed:{...(0,_e.YP)("$_settings",["settings.mailersend.api_key","settings.mailersend.has_pro_plan","settings.mail.from_email","settings.mail.from_name","settings.mail.from_email_force","settings.mail.from_name_force"])},methods:{areRequiredFieldsValid(){return""===this.api_key&&this.field_errors.push("api_key"),""===this.from_email&&this.field_errors.push("from_email"),0===this.field_errors.length},removeFieldError(e){this.field_errors=this.field_errors.filter((t=>t!==e))},errorDetected(e,t){this.field_errors.push(t)}}},Mi=Si,Pi=(0,d.A)(Mi,yi,Ci,!1,null,null,null),Ei=Pi.exports,Fi=function(){var e=this,t=e._self._c;return t("div",{staticClass:"wp-mail-smtp-setup-wizard-step-configure-mailer-settings wp-mail-smtp-setup-wizard-step-configure-mailer-settings-mailgun"},[t("p",{staticClass:"mailer-description",domProps:{innerHTML:e._s(e.description)}}),t("p",{staticClass:"mailer-description mailer-description-links"},[t("a",{staticClass:"wp-mail-smtp-link",attrs:{href:e.documentation_link_url,target:"_blank",rel:"noopener noreferrer"}},[e._v(e._s(e.text_documentation_link))])]),t("div",{staticClass:"wp-mail-smtp-setup-wizard-form"},[t("settings-input-text",{attrs:{name:"api_key",type:"password",constant:"WPMS_MAILGUN_API_KEY",label:e.text_api_key_label,description:e.text_api_key_description,is_error:e.field_errors.includes("api_key")},on:{is_error_update:function(t){return e.removeFieldError("api_key")}},model:{value:e.api_key,callback:function(t){e.api_key=t},expression:"api_key"}}),t("settings-input-text",{attrs:{name:"domain",constant:"WPMS_MAILGUN_DOMAIN",label:e.text_domain_label,description:e.text_domain_description,is_error:e.field_errors.includes("domain")},on:{is_error_update:function(t){return e.removeFieldError("domain")}},model:{value:e.domain,callback:function(t){e.domain=t},expression:"domain"}}),t("settings-input-radio",{attrs:{name:"region",constant:"WPMS_MAILGUN_REGION",label:e.text_region_label,options:e.regionOptions,description:e.text_region_description},model:{value:e.region,callback:function(t){e.region=t},expression:"region"}}),t("settings-input-text",{attrs:{name:"from_name",constant:"WPMS_MAIL_FROM_NAME",label:e.text_from_name_label,description:e.text_from_name_description},model:{value:e.from_name,callback:function(t){e.from_name=t},expression:"from_name"}}),t("settings-input-switch",{attrs:{classname:"sub_setting",name:"from_name_force",constant:"WPMS_MAIL_FROM_NAME_FORCE",title:e.text_force_from_name_title,label:e.text_force_from_name_label},model:{value:e.from_name_force,callback:function(t){e.from_name_force=t},expression:"from_name_force"}}),t("settings-input-text",{attrs:{name:"from_email",type:"email",constant:"WPMS_MAIL_FROM",label:e.text_from_email_label,description:e.text_from_email_description,is_error:e.field_errors.includes("from_email")},on:{is_error_update:function(t){return e.removeFieldError("from_email")},error_detected:t=>e.errorDetected(t,"from_email")},model:{value:e.from_email,callback:function(t){e.from_email=t},expression:"from_email"}}),t("settings-input-switch",{attrs:{classname:"sub_setting",name:"from_email_force",constant:"WPMS_MAIL_FROM_FORCE",title:e.text_force_from_email_title,label:e.text_force_from_email_label},model:{value:e.from_email_force,callback:function(t){e.from_email_force=t},expression:"from_email_force"}})],1)])},Bi=[],Ti={name:"WizardStepConfigureMailerMailgun",components:{SettingsInputText:Ue,SettingsInputRadio:Zt,SettingsInputSwitch:ti},data(){return{mailer:"mailgun",text_api_key_label:(0,l.__)("Mailgun API Key","wp-mail-smtp"),text_domain_label:(0,l.__)("Domain Name","wp-mail-smtp"),text_region_label:(0,l.__)("Region","wp-mail-smtp"),text_api_key_description:(0,l.nv)((0,l.__)('%1$sFollow this link%2$s to get a Mailgun API Key. Generate a key in the "Mailgun API Keys" section.',"wp-mail-smtp"),'',""),text_domain_description:(0,l.nv)((0,l.__)("%1$sFollow this link%2$s to get a Domain Name from Mailgun.","wp-mail-smtp"),'',""),text_region_description:(0,l.nv)((0,l.__)("Define which endpoint you want to use for sending messages. If you are operating under EU laws, you may be required to use EU region. %1$sMore information%2$s on Mailgun.com.","wp-mail-smtp"),'',""),text_from_name_label:(0,l.__)("From Name","wp-mail-smtp"),text_force_from_name_title:(0,l.__)("Force From Name","wp-mail-smtp"),text_from_email_label:(0,l.__)("From Email","wp-mail-smtp"),text_force_from_email_title:(0,l.__)("Force From Email","wp-mail-smtp"),text_force_from_name_label:(0,l.__)("If enabled, the From Name setting above will be used for all emails, ignoring values set by other plugins.","wp-mail-smtp"),text_force_from_email_label:(0,l.__)("If enabled, the From Email setting above will be used for all emails, ignoring values set by other plugins.","wp-mail-smtp"),text_from_name_description:(0,l.__)("The name that emails are sent from.","wp-mail-smtp"),text_from_email_description:(0,l.__)("The email address that emails are sent from.","wp-mail-smtp"),text_documentation_link:(0,l.__)("Read how to set up Mailgun","wp-mail-smtp"),description:this.$wpms.mailer_options.mailgun.description.substr(0,this.$wpms.mailer_options.mailgun.description.indexOf(" ")),documentation_link_url:this.$getUTMUrl("https://wpmailsmtp.com/docs/how-to-set-up-the-mailgun-mailer-in-wp-mail-smtp/",{content:"Read how to set up Mailgun"}),regionOptions:[{label:(0,l.__)("US","wp-mail-smtp"),value:"US"},{label:(0,l.__)("EU","wp-mail-smtp"),value:"EU"}],field_errors:[]}},computed:{...(0,_e.YP)("$_settings",["settings.mailgun.api_key","settings.mailgun.domain","settings.mailgun.region","settings.mail.from_email","settings.mail.from_name","settings.mail.from_email_force","settings.mail.from_name_force"])},methods:{areRequiredFieldsValid(){return""===this.api_key&&this.field_errors.push("api_key"),""===this.domain&&this.field_errors.push("domain"),""===this.from_email&&this.field_errors.push("from_email"),0===this.field_errors.length},removeFieldError(e){this.field_errors=this.field_errors.filter((t=>t!==e))},errorDetected(e,t){this.field_errors.push(t)}}},Ii=Ti,Di=(0,d.A)(Ii,Fi,Bi,!1,null,null,null),Oi=Di.exports,zi=function(){var e=this,t=e._self._c;return t("div",{staticClass:"wp-mail-smtp-setup-wizard-step-configure-mailer-settings wp-mail-smtp-setup-wizard-step-configure-mailer-settings-mailjet"},[t("p",{staticClass:"mailer-description",domProps:{innerHTML:e._s(e.description)}}),t("p",{staticClass:"mailer-description mailer-description-links"},[t("a",{staticClass:"wp-mail-smtp-link wp-mail-smtp-link-docs",attrs:{href:e.documentation_link_url,target:"_blank",rel:"noopener noreferrer"}},[e._v(e._s(e.text_documentation_link))])]),t("div",{staticClass:"wp-mail-smtp-setup-wizard-form"},[t("settings-input-text",{attrs:{name:"api_key",type:"password",constant:"WPMS_MAILJET_API_KEY",label:e.text_api_key_label,description:e.text_api_key_description,is_error:e.field_errors.includes("api_key")},on:{is_error_update:function(t){return e.removeFieldError("api_key")}},model:{value:e.api_key,callback:function(t){e.api_key=t},expression:"api_key"}}),t("settings-input-text",{attrs:{name:"secret_key",type:"password",constant:"WPMS_MAILJET_SECRET_KEY",label:e.text_secret_key_label,description:e.text_secret_key_description,is_error:e.field_errors.includes("secret_key")},on:{is_error_update:function(t){return e.removeFieldError("secret_key")}},model:{value:e.secret_key,callback:function(t){e.secret_key=t},expression:"secret_key"}}),t("settings-input-text",{attrs:{name:"from_name",constant:"WPMS_MAIL_FROM_NAME",label:e.text_from_name_label,description:e.text_from_name_description},model:{value:e.from_name,callback:function(t){e.from_name=t},expression:"from_name"}}),t("settings-input-switch",{attrs:{classname:"sub_setting",name:"from_name_force",constant:"WPMS_MAIL_FROM_NAME_FORCE",title:e.text_force_from_name_title,label:e.text_force_from_name_label},model:{value:e.from_name_force,callback:function(t){e.from_name_force=t},expression:"from_name_force"}}),t("settings-input-text",{attrs:{name:"from_email",type:"email",constant:"WPMS_MAIL_FROM",label:e.text_from_email_label,description:e.text_from_email_description,is_error:e.field_errors.includes("from_email")},on:{is_error_update:function(t){return e.removeFieldError("from_email")},error_detected:t=>e.errorDetected(t,"from_email")},model:{value:e.from_email,callback:function(t){e.from_email=t},expression:"from_email"}}),t("settings-input-switch",{attrs:{classname:"sub_setting",name:"from_email_force",constant:"WPMS_MAIL_FROM_FORCE",title:e.text_force_from_email_title,label:e.text_force_from_email_label},model:{value:e.from_email_force,callback:function(t){e.from_email_force=t},expression:"from_email_force"}})],1)])},Li=[],Ri={name:"WizardStepConfigureMailerMailjet",components:{SettingsInputText:Ue,SettingsInputSwitch:ti},data(){return{mailer:"mailjet",text_api_key_label:(0,l.__)("API Key","wp-mail-smtp"),text_api_key_description:(0,l.nv)((0,l.__)("Follow this link to get the API key from Mailjet: %1$sAPI Key Management%2$s.","wp-mail-smtp"),'',""),text_secret_key_label:(0,l.__)("Secret Key","wp-mail-smtp"),text_secret_key_description:(0,l.nv)((0,l.__)("Follow this link to get the Secret key from Mailjet: %1$sAPI Key Management%2$s.","wp-mail-smtp"),'',""),text_from_name_label:(0,l.__)("From Name","wp-mail-smtp"),text_force_from_name_title:(0,l.__)("Force From Name","wp-mail-smtp"),text_from_email_label:(0,l.__)("From Email","wp-mail-smtp"),text_force_from_email_title:(0,l.__)("Force From Email","wp-mail-smtp"),text_force_from_name_label:(0,l.__)("If enabled, the From Name setting above will be used for all emails, ignoring values set by other plugins.","wp-mail-smtp"),text_force_from_email_label:(0,l.__)("If enabled, the From Email setting above will be used for all emails, ignoring values set by other plugins.","wp-mail-smtp"),text_from_name_description:(0,l.__)("The name that emails are sent from.","wp-mail-smtp"),text_from_email_description:(0,l.__)("The email address that emails are sent from.","wp-mail-smtp"),text_documentation_link:(0,l.__)("Read how to set up Mailjet","wp-mail-smtp"),description:this.$wpms.mailer_options.mailjet.description.substr(0,this.$wpms.mailer_options.mailjet.description.lastIndexOf("
")),documentation_link_url:this.$getUTMUrl("https://wpmailsmtp.com/docs/how-to-set-up-the-mailjet-mailer-in-wp-mail-smtp/",{content:"Read how to set up Mailjet"}),field_errors:[]}},computed:{...(0,_e.YP)("$_settings",["settings.mailjet.api_key","settings.mailjet.secret_key","settings.mail.from_email","settings.mail.from_name","settings.mail.from_email_force","settings.mail.from_name_force"])},methods:{areRequiredFieldsValid(){return""===this.api_key&&this.field_errors.push("api_key"),""===this.from_email&&this.field_errors.push("from_email"),0===this.field_errors.length},removeFieldError(e){this.field_errors=this.field_errors.filter((t=>t!==e))},errorDetected(e,t){this.field_errors.push(t)}}},Wi=Ri,Ni=(0,d.A)(Wi,zi,Li,!1,null,null,null),Ui=Ni.exports,Qi=function(){var e=this,t=e._self._c;return t("div",{staticClass:"wp-mail-smtp-setup-wizard-step-configure-mailer-settings wp-mail-smtp-setup-wizard-step-configure-mailer-settings-sendgrid"},[t("p",{staticClass:"mailer-description",domProps:{innerHTML:e._s(e.description)}}),t("p",{staticClass:"mailer-description mailer-description-links"},[t("a",{staticClass:"wp-mail-smtp-link",attrs:{href:e.documentation_link_url,target:"_blank",rel:"noopener noreferrer"}},[e._v(e._s(e.text_documentation_link))])]),t("div",{staticClass:"wp-mail-smtp-setup-wizard-form"},[t("settings-input-text",{attrs:{name:"api_key",type:"password",constant:"WPMS_SENDGRID_API_KEY",label:e.text_api_key_label,description:e.text_api_key_description,is_error:e.field_errors.includes("api_key")},on:{is_error_update:function(t){return e.removeFieldError("api_key")}},model:{value:e.api_key,callback:function(t){e.api_key=t},expression:"api_key"}}),t("settings-input-text",{attrs:{name:"domain",constant:"WPMS_SENDGRID_DOMAIN",label:e.text_domain_label,description:e.text_domain_description},model:{value:e.domain,callback:function(t){e.domain=t},expression:"domain"}}),t("settings-input-text",{attrs:{name:"from_name",constant:"WPMS_MAIL_FROM_NAME",label:e.text_from_name_label,description:e.text_from_name_description},model:{value:e.from_name,callback:function(t){e.from_name=t},expression:"from_name"}}),t("settings-input-switch",{attrs:{classname:"sub_setting",name:"from_name_force",constant:"WPMS_MAIL_FROM_NAME_FORCE",title:e.text_force_from_name_title,label:e.text_force_from_name_label},model:{value:e.from_name_force,callback:function(t){e.from_name_force=t},expression:"from_name_force"}}),t("settings-input-text",{attrs:{name:"from_email",type:"email",constant:"WPMS_MAIL_FROM",label:e.text_from_email_label,description:e.text_from_email_description,is_error:e.field_errors.includes("from_email")},on:{is_error_update:function(t){return e.removeFieldError("from_email")},error_detected:t=>e.errorDetected(t,"from_email")},model:{value:e.from_email,callback:function(t){e.from_email=t},expression:"from_email"}}),t("settings-input-switch",{attrs:{classname:"sub_setting",name:"from_email_force",constant:"WPMS_MAIL_FROM_FORCE",title:e.text_force_from_email_title,label:e.text_force_from_email_label},model:{value:e.from_email_force,callback:function(t){e.from_email_force=t},expression:"from_email_force"}})],1)])},Zi=[],Gi={name:"WizardStepConfigureMailerSendgrid",components:{SettingsInputText:Ue,SettingsInputSwitch:ti},data(){return{mailer:"sendgrid",text_api_key_label:(0,l.__)("API Key","wp-mail-smtp"),text_domain_label:(0,l.__)("Sending Domain","wp-mail-smtp"),text_api_key_description:(0,l.nv)((0,l.__)("%1$sFollow this link%2$s to get an API Key for Sendgrid.","wp-mail-smtp"),'',"")+" "+(0,l.nv)((0,l.__)("To send emails you will need only a %1$sMail Send%2$s access level for this API key.","wp-mail-smtp"),"",""),text_domain_description:(0,l.nv)((0,l.__)("Please input the sending domain/subdomain you configured in your SendGrid dashboard. More information can be found in our %1$sSendGrid documentation%2$s","wp-mail-smtp"),'',""),text_from_name_label:(0,l.__)("From Name","wp-mail-smtp"),text_force_from_name_title:(0,l.__)("Force From Name","wp-mail-smtp"),text_from_email_label:(0,l.__)("From Email","wp-mail-smtp"),text_force_from_email_title:(0,l.__)("Force From Email","wp-mail-smtp"),text_force_from_name_label:(0,l.__)("If enabled, the From Name setting above will be used for all emails, ignoring values set by other plugins.","wp-mail-smtp"),text_force_from_email_label:(0,l.__)("If enabled, the From Email setting above will be used for all emails, ignoring values set by other plugins.","wp-mail-smtp"),text_from_name_description:(0,l.__)("The name that emails are sent from.","wp-mail-smtp"),text_from_email_description:(0,l.__)("The email address that emails are sent from.","wp-mail-smtp"),text_documentation_link:(0,l.__)("Read how to set up SendGrid","wp-mail-smtp"),description:this.$wpms.mailer_options.sendgrid.description.substr(0,this.$wpms.mailer_options.sendgrid.description.indexOf(" ")),documentation_link_url:this.$getUTMUrl("https://wpmailsmtp.com/docs/how-to-set-up-the-sendgrid-mailer-in-wp-mail-smtp/",{content:"Read how to set up Sendgrid"}),field_errors:[]}},computed:{...(0,_e.YP)("$_settings",["settings.sendgrid.api_key","settings.sendgrid.domain","settings.mail.from_email","settings.mail.from_name","settings.mail.from_email_force","settings.mail.from_name_force"])},methods:{areRequiredFieldsValid(){return""===this.api_key&&this.field_errors.push("api_key"),""===this.from_email&&this.field_errors.push("from_email"),0===this.field_errors.length},removeFieldError(e){this.field_errors=this.field_errors.filter((t=>t!==e))},errorDetected(e,t){this.field_errors.push(t)}}},Yi=Gi,Hi=(0,d.A)(Yi,Qi,Zi,!1,null,null,null),Vi=Hi.exports,Ki=function(){var e=this,t=e._self._c;return t("div",{staticClass:"wp-mail-smtp-setup-wizard-step-configure-mailer-settings wp-mail-smtp-setup-wizard-step-configure-mailer-settings-smtp2go"},[t("p",{staticClass:"mailer-description",domProps:{innerHTML:e._s(e.description)}}),t("p",{staticClass:"mailer-description mailer-description-links"},[t("a",{staticClass:"wp-mail-smtp-link wp-mail-smtp-link-docs",attrs:{href:e.documentation_link_url,target:"_blank",rel:"noopener noreferrer"}},[e._v(e._s(e.text_documentation_link))])]),t("div",{staticClass:"wp-mail-smtp-setup-wizard-form"},[t("settings-input-text",{attrs:{name:"api_key",type:"password",constant:"WPMS_SMTP2GO_API_KEY",label:e.text_api_key_label,description:e.text_api_key_description,is_error:e.field_errors.includes("api_key")},on:{is_error_update:function(t){return e.removeFieldError("api_key")}},model:{value:e.api_key,callback:function(t){e.api_key=t},expression:"api_key"}}),t("settings-input-text",{attrs:{name:"from_name",constant:"WPMS_MAIL_FROM_NAME",label:e.text_from_name_label,description:e.text_from_name_description},model:{value:e.from_name,callback:function(t){e.from_name=t},expression:"from_name"}}),t("settings-input-switch",{attrs:{classname:"sub_setting",name:"from_name_force",constant:"WPMS_MAIL_FROM_NAME_FORCE",title:e.text_force_from_name_title,label:e.text_force_from_name_label},model:{value:e.from_name_force,callback:function(t){e.from_name_force=t},expression:"from_name_force"}}),t("settings-input-text",{attrs:{name:"from_email",type:"email",constant:"WPMS_MAIL_FROM",label:e.text_from_email_label,description:e.text_from_email_description,is_error:e.field_errors.includes("from_email")},on:{is_error_update:function(t){return e.removeFieldError("from_email")},error_detected:t=>e.errorDetected(t,"from_email")},model:{value:e.from_email,callback:function(t){e.from_email=t},expression:"from_email"}}),t("settings-input-switch",{attrs:{classname:"sub_setting",name:"from_email_force",constant:"WPMS_MAIL_FROM_FORCE",title:e.text_force_from_email_title,label:e.text_force_from_email_label},model:{value:e.from_email_force,callback:function(t){e.from_email_force=t},expression:"from_email_force"}})],1)])},qi=[],Ji={name:"WizardStepConfigureMailerSMTP2GO",components:{SettingsInputText:Ue,SettingsInputSwitch:ti},data(){return{mailer:"smtp2go",text_api_key_label:(0,l.__)("API Key","wp-mail-smtp"),text_api_key_description:(0,l.nv)((0,l.__)("Generate an API key on the Sending ā API Keys page in your %1$scontrol panel%2$s.","wp-mail-smtp"),'',""),text_from_name_label:(0,l.__)("From Name","wp-mail-smtp"),text_force_from_name_title:(0,l.__)("Force From Name","wp-mail-smtp"),text_from_email_label:(0,l.__)("From Email","wp-mail-smtp"),text_force_from_email_title:(0,l.__)("Force From Email","wp-mail-smtp"),text_force_from_name_label:(0,l.__)("If enabled, the From Name setting above will be used for all emails, ignoring values set by other plugins.","wp-mail-smtp"),text_force_from_email_label:(0,l.__)("If enabled, the From Email setting above will be used for all emails, ignoring values set by other plugins.","wp-mail-smtp"),text_from_name_description:(0,l.__)("The name that emails are sent from.","wp-mail-smtp"),text_from_email_description:(0,l.__)("The email address that emails are sent from.","wp-mail-smtp"),text_documentation_link:(0,l.__)("Read how to set up SMTP2GO","wp-mail-smtp"),description:this.$wpms.mailer_options.smtp2go.description.substr(0,this.$wpms.mailer_options.smtp2go.description.lastIndexOf("
")),documentation_link_url:this.$getUTMUrl("https://wpmailsmtp.com/docs/how-to-set-up-the-smtp2go-mailer-in-wp-mail-smtp/",{content:"Read how to set up SMTP2GO"}),field_errors:[]}},computed:{...(0,_e.YP)("$_settings",["settings.smtp2go.api_key","settings.mail.from_email","settings.mail.from_name","settings.mail.from_email_force","settings.mail.from_name_force"])},methods:{areRequiredFieldsValid(){return""===this.api_key&&this.field_errors.push("api_key"),""===this.from_email&&this.field_errors.push("from_email"),0===this.field_errors.length},removeFieldError(e){this.field_errors=this.field_errors.filter((t=>t!==e))},errorDetected(e,t){this.field_errors.push(t)}}},ji=Ji,Xi=(0,d.A)(ji,Ki,qi,!1,null,null,null),$i=Xi.exports,es=function(){var e=this,t=e._self._c;return t("div",{staticClass:"wp-mail-smtp-setup-wizard-step-configure-mailer-settings wp-mail-smtp-setup-wizard-step-configure-mailer-settings-sparkpost"},[t("p",{staticClass:"mailer-description",domProps:{innerHTML:e._s(e.description)}}),t("p",{staticClass:"mailer-description mailer-description-links"},[t("a",{staticClass:"wp-mail-smtp-link wp-mail-smtp-link-docs",attrs:{href:e.documentation_link_url,target:"_blank",rel:"noopener noreferrer"}},[e._v(e._s(e.text_documentation_link))])]),t("div",{staticClass:"wp-mail-smtp-setup-wizard-form"},[t("settings-input-text",{attrs:{name:"api_key",type:"password",constant:"WPMS_SPARKPOST_API_KEY",label:e.text_api_key_label,description:e.text_api_key_description,is_error:e.field_errors.includes("api_key")},on:{is_error_update:function(t){return e.removeFieldError("api_key")}},model:{value:e.api_key,callback:function(t){e.api_key=t},expression:"api_key"}}),t("settings-input-radio",{attrs:{name:"region",constant:"WPMS_SPARKPOST_REGION",label:e.text_region_label,options:e.regionOptions,description:e.text_region_description},model:{value:e.region,callback:function(t){e.region=t},expression:"region"}}),t("settings-input-text",{attrs:{name:"from_name",constant:"WPMS_MAIL_FROM_NAME",label:e.text_from_name_label,description:e.text_from_name_description},model:{value:e.from_name,callback:function(t){e.from_name=t},expression:"from_name"}}),t("settings-input-switch",{attrs:{classname:"sub_setting",name:"from_name_force",constant:"WPMS_MAIL_FROM_NAME_FORCE",title:e.text_force_from_name_title,label:e.text_force_from_name_label},model:{value:e.from_name_force,callback:function(t){e.from_name_force=t},expression:"from_name_force"}}),t("settings-input-text",{attrs:{name:"from_email",type:"email",constant:"WPMS_MAIL_FROM",label:e.text_from_email_label,description:e.text_from_email_description,is_error:e.field_errors.includes("from_email")},on:{is_error_update:function(t){return e.removeFieldError("from_email")},error_detected:t=>e.errorDetected(t,"from_email")},model:{value:e.from_email,callback:function(t){e.from_email=t},expression:"from_email"}}),t("settings-input-switch",{attrs:{classname:"sub_setting",name:"from_email_force",constant:"WPMS_MAIL_FROM_FORCE",title:e.text_force_from_email_title,label:e.text_force_from_email_label},model:{value:e.from_email_force,callback:function(t){e.from_email_force=t},expression:"from_email_force"}})],1)])},ts=[],is={name:"WizardStepConfigureMailerSparkPost",components:{SettingsInputText:Ue,SettingsInputRadio:Zt,SettingsInputSwitch:ti},data(){return{mailer:"sparkpost",text_api_key_label:(0,l.__)("API Key","wp-mail-smtp"),text_region_label:(0,l.__)("Region","wp-mail-smtp"),text_region_description:(0,l.nv)((0,l.__)("Select your SparkPost account region. %1$sMore information%2$s on SparkPost.","wp-mail-smtp"),'',""),text_from_name_label:(0,l.__)("From Name","wp-mail-smtp"),text_force_from_name_title:(0,l.__)("Force From Name","wp-mail-smtp"),text_from_email_label:(0,l.__)("From Email","wp-mail-smtp"),text_force_from_email_title:(0,l.__)("Force From Email","wp-mail-smtp"),text_force_from_name_label:(0,l.__)("If enabled, the From Name setting above will be used for all emails, ignoring values set by other plugins.","wp-mail-smtp"),text_force_from_email_label:(0,l.__)("If enabled, the From Email setting above will be used for all emails, ignoring values set by other plugins.","wp-mail-smtp"),text_from_name_description:(0,l.__)("The name that emails are sent from.","wp-mail-smtp"),text_from_email_description:(0,l.__)("The email address that emails are sent from.","wp-mail-smtp"),text_documentation_link:(0,l.__)("Read how to set up SparkPost","wp-mail-smtp"),description:this.$wpms.mailer_options.sparkpost.description.substr(0,this.$wpms.mailer_options.sparkpost.description.lastIndexOf("
")),documentation_link_url:this.$getUTMUrl("https://wpmailsmtp.com/docs/how-to-set-up-the-sparkpost-mailer-in-wp-mail-smtp/",{content:"Read how to set up SparkPost"}),regionOptions:[{label:(0,l.__)("US","wp-mail-smtp"),value:"US"},{label:(0,l.__)("EU","wp-mail-smtp"),value:"EU"}],field_errors:[]}},computed:{...(0,_e.YP)("$_settings",["settings.sparkpost.api_key","settings.sparkpost.region","settings.mail.from_email","settings.mail.from_name","settings.mail.from_email_force","settings.mail.from_name_force"]),text_api_key_description:function(){let e="EU"===this.region?"eu.":"";return(0,l.nv)((0,l.__)("%1$sFollow this link%2$s to get an API Key for SparkPost.","wp-mail-smtp"),'',"")}},methods:{areRequiredFieldsValid(){return""===this.api_key&&this.field_errors.push("api_key"),""===this.from_email&&this.field_errors.push("from_email"),0===this.field_errors.length},removeFieldError(e){this.field_errors=this.field_errors.filter((t=>t!==e))},errorDetected(e,t){this.field_errors.push(t)}}},ss=is,as=(0,d.A)(ss,es,ts,!1,null,null,null),ns=as.exports,rs=function(){var e=this,t=e._self._c;return t("div",{staticClass:"wp-mail-smtp-setup-wizard-step-configure-mailer-settings wp-mail-smtp-setup-wizard-step-configure-mailer-settings-postmark"},[t("p",{staticClass:"mailer-description",domProps:{innerHTML:e._s(e.description)}}),t("p",{staticClass:"mailer-description mailer-description-links"},[t("a",{staticClass:"wp-mail-smtp-link wp-mail-smtp-link-docs",attrs:{href:e.documentation_link_url,target:"_blank",rel:"noopener noreferrer"}},[e._v(e._s(e.text_documentation_link))])]),t("div",{staticClass:"wp-mail-smtp-setup-wizard-form"},[t("settings-input-text",{attrs:{name:"server_api_token",type:"password",constant:"WPMS_POSTMARK_SERVER_API_TOKEN",label:e.text_server_api_token_label,description:e.text_server_api_token_description,is_error:e.field_errors.includes("server_api_token")},on:{is_error_update:function(t){return e.removeFieldError("server_api_token")}},model:{value:e.server_api_token,callback:function(t){e.server_api_token=t},expression:"server_api_token"}}),t("settings-input-text",{attrs:{name:"message_stream",constant:"WPMS_POSTMARK_MESSAGE_STREAM",label:e.text_message_stream_label,description:e.text_message_stream_description},model:{value:e.message_stream,callback:function(t){e.message_stream=t},expression:"message_stream"}}),t("settings-input-text",{attrs:{name:"from_name",constant:"WPMS_MAIL_FROM_NAME",label:e.text_from_name_label,description:e.text_from_name_description},model:{value:e.from_name,callback:function(t){e.from_name=t},expression:"from_name"}}),t("settings-input-switch",{attrs:{classname:"sub_setting",name:"from_name_force",constant:"WPMS_MAIL_FROM_NAME_FORCE",title:e.text_force_from_name_title,label:e.text_force_from_name_label},model:{value:e.from_name_force,callback:function(t){e.from_name_force=t},expression:"from_name_force"}}),t("settings-input-text",{attrs:{name:"from_email",type:"email",constant:"WPMS_MAIL_FROM",label:e.text_from_email_label,description:e.text_from_email_description,is_error:e.field_errors.includes("from_email")},on:{is_error_update:function(t){return e.removeFieldError("from_email")},error_detected:t=>e.errorDetected(t,"from_email")},model:{value:e.from_email,callback:function(t){e.from_email=t},expression:"from_email"}}),t("settings-input-switch",{attrs:{classname:"sub_setting",name:"from_email_force",constant:"WPMS_MAIL_FROM_FORCE",title:e.text_force_from_email_title,label:e.text_force_from_email_label},model:{value:e.from_email_force,callback:function(t){e.from_email_force=t},expression:"from_email_force"}})],1)])},os=[],ls={name:"WizardStepConfigureMailerPostmark",components:{SettingsInputText:Ue,SettingsInputSwitch:ti},data(){return{mailer:"postmark",text_server_api_token_label:(0,l.__)("Server API Token","wp-mail-smtp"),text_message_stream_label:(0,l.__)("Message Stream ID","wp-mail-smtp"),text_server_api_token_description:(0,l.nv)((0,l.__)("%1$sFollow this link%2$s to get a Server API Token for Postmark.","wp-mail-smtp"),'',""),text_message_stream_description:(0,l.nv)((0,l.__)("Message Stream ID is optional. By default outbound (Default Transactional Stream) will be used. More information can be found in our %1$sPostmark documentation%2$s.","wp-mail-smtp"),'',""),text_from_name_label:(0,l.__)("From Name","wp-mail-smtp"),text_force_from_name_title:(0,l.__)("Force From Name","wp-mail-smtp"),text_from_email_label:(0,l.__)("From Email","wp-mail-smtp"),text_force_from_email_title:(0,l.__)("Force From Email","wp-mail-smtp"),text_force_from_name_label:(0,l.__)("If enabled, the From Name setting above will be used for all emails, ignoring values set by other plugins.","wp-mail-smtp"),text_force_from_email_label:(0,l.__)("If enabled, the From Email setting above will be used for all emails, ignoring values set by other plugins.","wp-mail-smtp"),text_from_name_description:(0,l.__)("The name that emails are sent from.","wp-mail-smtp"),text_from_email_description:(0,l.__)("The email address that emails are sent from.","wp-mail-smtp"),text_documentation_link:(0,l.__)("Read how to set up Postmark","wp-mail-smtp"),description:this.$wpms.mailer_options.postmark.description.substr(0,this.$wpms.mailer_options.postmark.description.lastIndexOf("
")),documentation_link_url:this.$getUTMUrl("https://wpmailsmtp.com/docs/how-to-set-up-the-postmark-mailer-in-wp-mail-smtp/",{content:"Read how to set up Postmark"}),field_errors:[]}},computed:{...(0,_e.YP)("$_settings",["settings.postmark.server_api_token","settings.postmark.message_stream","settings.mail.from_email","settings.mail.from_name","settings.mail.from_email_force","settings.mail.from_name_force"])},methods:{areRequiredFieldsValid(){return""===this.server_api_token&&this.field_errors.push("server_api_token"),""===this.from_email&&this.field_errors.push("from_email"),0===this.field_errors.length},removeFieldError(e){this.field_errors=this.field_errors.filter((t=>t!==e))},errorDetected(e,t){this.field_errors.push(t)}}},ms=ls,ps=(0,d.A)(ms,rs,os,!1,null,null,null),_s=ps.exports,cs=function(){var e=this,t=e._self._c;return t("div",{staticClass:"wp-mail-smtp-setup-wizard-step-configure-mailer-settings wp-mail-smtp-setup-wizard-step-configure-mailer-settings-amazonses"},[t("p",{staticClass:"mailer-description",domProps:{innerHTML:e._s(e.description)}}),t("p",{staticClass:"mailer-description mailer-description-links"},[t("b",[t("a",{staticClass:"wp-mail-smtp-link",attrs:{href:e.documentation_link_url,target:"_blank",rel:"noopener noreferrer"}},[e._v(e._s(e.text_documentation_link))])])]),e.is_ssl?t("div",{staticClass:"wp-mail-smtp-setup-wizard-form"},[t("settings-input-text",{attrs:{name:"client_id",constant:"WPMS_AMAZONSES_CLIENT_ID",label:e.text_client_id_label,is_error:e.field_errors.includes("client_id")},on:{is_error_update:function(t){return e.removeFieldError("client_id")}},model:{value:e.client_id,callback:function(t){e.client_id=t},expression:"client_id"}}),t("settings-input-text",{attrs:{name:"client_secret",type:"password",constant:"WPMS_AMAZONSES_CLIENT_SECRET",label:e.text_client_secret_label,is_error:e.field_errors.includes("client_secret")},on:{is_error_update:function(t){return e.removeFieldError("client_secret")}},model:{value:e.client_secret,callback:function(t){e.client_secret=t},expression:"client_secret"}}),t("settings-input-select",{attrs:{name:"region",constant:"WPMS_AMAZONSES_REGION",label:e.text_region_label,options:e.regionOptions,description:e.text_region_description,is_error:e.field_errors.includes("region")},on:{is_error_update:function(t){return e.removeFieldError("region")}},model:{value:e.region,callback:function(t){e.region=t},expression:"region"}}),e.is_api_auth_missing?e._e():t("div",[e.display_identities?t("div",[t("div",{staticClass:"wp-mail-smtp-separator wp-mail-smtp-separator-big-margin"}),t("settings-amazon-s-e-s-identities",{attrs:{options:e.identities,label:e.text_identities_label,columns:e.identities_columns}})],1):e._e(),t("div",{staticClass:"wp-mail-smtp-separator wp-mail-smtp-separator-big-margin"}),t("settings-input-text",{attrs:{name:"from_name",constant:"WPMS_MAIL_FROM_NAME",label:e.text_from_name_label,description:e.text_from_name_description},model:{value:e.from_name,callback:function(t){e.from_name=t},expression:"from_name"}}),t("settings-input-switch",{attrs:{classname:"sub_setting",name:"from_name_force",constant:"WPMS_MAIL_FROM_NAME_FORCE",title:e.text_force_from_name_title,label:e.text_force_from_name_label},model:{value:e.from_name_force,callback:function(t){e.from_name_force=t},expression:"from_name_force"}}),t("settings-input-text",{attrs:{name:"from_email",type:"email",constant:"WPMS_MAIL_FROM",label:e.text_from_email_label,description:e.text_from_email_description,is_error:e.field_errors.includes("from_email")},on:{is_error_update:function(t){return e.removeFieldError("from_email")},error_detected:t=>e.errorDetected(t,"from_email")},model:{value:e.from_email,callback:function(t){e.from_email=t},expression:"from_email"}}),t("settings-input-switch",{attrs:{classname:"sub_setting",name:"from_email_force",constant:"WPMS_MAIL_FROM_FORCE",title:e.text_force_from_email_title,label:e.text_force_from_email_label},model:{value:e.from_email_force,callback:function(t){e.from_email_force=t},expression:"from_email_force"}})],1)],1):t("div",{staticClass:"wp-mail-smtp-setup-wizard-form"},[t("div",{staticClass:"wp-mail-smtp-notice wp-mail-smtp-notice--error"},[t("p",[t("span",[e._v(e._s(e.text_no_ssl))]),e._v(" "),t("a",{attrs:{href:"https://www.wpbeginner.com/wp-tutorials/how-to-add-ssl-and-https-in-wordpress/",target:"_blank",rel:"noopener"}},[e._v(e._s(e.text_no_ssl_link_text))]),e._v(".")]),t("p",[e._v(e._s(e.text_no_ssl_diff_mailer))])])])])},ds=[],us=i(181),fs=i.n(us),hs=function(){var e=this,t=e._self._c;return t("div",{staticClass:"settings-input-select",class:{"settings-input-select-error":e.field_error}},[t("label",{staticClass:"settings-input-label-container",attrs:{for:`wp-mail-smtp-settings-select-${e.name}`}},[t("span",{staticClass:"label"},[e._v(e._s(e.label))])]),t("div",{staticClass:"settings-input-select-container"},[t("select",{directives:[{name:"model",rawName:"v-model",value:e.selected,expression:"selected"}],attrs:{id:`wp-mail-smtp-settings-select-${e.name}`,name:e.name,readonly:e.disabled,disabled:e.is_constant_set},on:{change:function(t){var i=Array.prototype.filter.call(t.target.options,(function(e){return e.selected})).map((function(e){var t="_value"in e?e._value:e.value;return t}));e.selected=t.target.multiple?i:i[0]}}},e._l(e.options,(function(i){return t("option",{key:i.value,domProps:{value:i.value}},[e._v(" "+e._s(i.label)+" ")])})),0)]),e.description?t("p",{staticClass:"description",domProps:{innerHTML:e._s(e.description)}}):e._e(),e.is_constant_set?t("p",{staticClass:"description description--constant",domProps:{innerHTML:e._s(e.text_constant)}}):e._e()])},gs=[],ws={name:"SettingsInputSelect",props:{options:Array,label:String,name:String,value:String,description:String,constant:String,disabled:Boolean,is_error:Boolean},computed:{selected:{get(){return this.value},set(e){this.$emit("is_error_update",!1),this.$emit("input",e)}},field_error:{get(){return this.is_error},set(e){this.$emit("is_error_update",e)}},is_constant_set:function(){return this.$wpms.defined_constants.includes(this.constant)},text_constant:function(){return(0,l.__)("This setting is already configured with the WP Mail SMTP constant. To change it, please edit or remove the "+this.constant+" constant in your wp-config.php file.","wp-mail-smtp")}}},As=ws,bs=(0,d.A)(As,hs,gs,!1,null,null,null),vs=bs.exports,xs=function(){var e=this,t=e._self._c;return t("div",{staticClass:"settings-amazon-ses-identities"},[t("label",{staticClass:"settings-input-label-container"},[t("span",{staticClass:"label"},[e._v(e._s(e.label))]),e.tooltip?t("settings-info-tooltip",{attrs:{content:e.tooltip}}):e._e()],1),e.options?t("div",[e.options&&0!==e.options.length?t("p",{staticClass:"description"},[e._v(" "+e._s(e.text_identities_table_description)+" ")]):t("p",{staticClass:"description"},[t("strong",[e._v(e._s(e.text_no_registered_identities_title))]),e._v(" "+e._s(e.text_no_registered_identities_content)+" ")]),t("div",{staticClass:"ses-identities-container"},[e.options&&e.options.length>0?t("div",{staticClass:"ses-identities-table-container"},[t("table",[e.columns?t("tr",{staticClass:"ses-identity-columns"},e._l(e.filtered_columns,(function(i){return t("th",{key:i.key,class:`ses-identity-column ses-identity-column-${i.key}`},[e._v(" "+e._s(i.label)+" ")])})),0):e._e(),e._l(e.options,(function(i,s){return t("tr",{key:s},[t("td",[e._v(" "+e._s(i.value)+" ")]),t("td",[e._v(" "+e._s(i.type)+" ")]),t("td",[e._v(" "+e._s(i.status)+" ")])])})),e.show_identity_form?e._e():t("button",{staticClass:"wp-mail-smtp-button wp-mail-smtp-button-main wp-mail-smtp-button-small",attrs:{type:"button"},on:{click:function(t){return t.preventDefault(),e.addNewIdentity.apply(null,arguments)}}},[e._v(" "+e._s(e.text_add_new_identity)+" ")])],2)]):e._e(),e.show_identity_form||!e.options||0===e.options.length?t("div",{staticClass:"wp-mail-smtp-amazonses-identity-form"},[e.options&&0!==e.options.length?e._e():t("h3",[e._v(" "+e._s(e.text_verify_identity)+" ")]),t("div",{directives:[{name:"show",rawName:"v-show",value:1===e.verify_identity_step,expression:"verify_identity_step === 1"}],staticClass:"amazonses-identity-form-step"},[t("settings-input-radio",{attrs:{name:"identity_type",options:e.identity_type_options},model:{value:e.identity_type,callback:function(t){e.identity_type=t},expression:"identity_type"}}),t("p",{domProps:{textContent:e._s(e.verify_identity_text)}}),t("settings-input-text",{attrs:{name:"identity_value",placeholder:e.identity_value_placeholder},model:{value:e.identity_value,callback:function(t){e.identity_value=t},expression:"identity_value"}}),t("button",{staticClass:"wp-mail-smtp-button wp-mail-smtp-button-main wp-mail-smtp-button-small wp-mail-smtp-button-verify",attrs:{type:"button"},on:{click:function(t){return t.preventDefault(),e.verifyIdentity.apply(null,arguments)}}},[e.loading_verify_identity?t("spin-loader",{attrs:{color:"white"}}):t("span",[e._v(e._s(e.text_verify))])],1)],1),t("div",{directives:[{name:"show",rawName:"v-show",value:2===e.verify_identity_step&&"domain"===e.verify_identity_result.type,expression:"verify_identity_step === 2 && verify_identity_result.type === 'domain'"}],staticClass:"amazonses-identity-form-step amazonses-identity-form-step-domain"},[t("p",{domProps:{innerHTML:e._s(e.text_verify_identity_step2_domain_text)}}),t("div",{staticClass:"amazonses-dns-records"},[t("div",{staticClass:"amazonses-dns-records__row amazonses-dns-records__row--heading"},[t("div",{staticClass:"amazonses-dns-records__col amazonses-dns-records__col--heading"},[e._v(" "+e._s(e.text_name)+" ")]),t("div",{staticClass:"amazonses-dns-records__col amazonses-dns-records__col--heading"},[e._v(" "+e._s(e.text_value)+" ")])]),e._l(e.verify_identity_result.domain_dkim_dns_records,(function(e,i){return t("div",{key:e.value,staticClass:"amazonses-dns-records__row amazonses-dns-records__row--record"},[t("div",{staticClass:"amazonses-dns-records__col amazonses-dns-records__col--record"},[t("settings-input-text",{attrs:{name:`dns_record_name[${i}]`,value:e.name,readonly:"",copy:""}})],1),t("div",{staticClass:"amazonses-dns-records__col amazonses-dns-records__col--record"},[t("settings-input-text",{attrs:{name:`dns_record_value[${i}]`,value:e.value,readonly:"",copy:""}})],1)])}))],2)]),t("div",{directives:[{name:"show",rawName:"v-show",value:2===e.verify_identity_step&&"email"===e.verify_identity_result.type,expression:"verify_identity_step === 2 && verify_identity_result.type === 'email'"}],staticClass:"amazonses-identity-form-step"},[t("p",{staticClass:"ses-identities-email-success-notice"},[t("inline-svg",{staticClass:"icon",attrs:{src:i(9318),width:"16",height:"16"}}),e._v(" "),t("span",{domProps:{innerHTML:e._s(e.text_verify_identity_step2_email_text)}})],1)])]):e._e()])]):t("spin-loader",{attrs:{size:"md"}})],1)},ks=[],ys={name:"SettingsAmazonSESIdentities",components:{SettingsInfoTooltip:Le,SettingsInputRadio:Zt,SettingsInputText:Ue,SpinLoader:vt},props:{options:Array,columns:Array,label:String,tooltip:String},computed:{filtered_columns:function(){return this.columns.filter((e=>"action"!==e.key))},identity_value_placeholder:function(){return"domain"===this.identity_type?(0,l.__)("Please enter a domain","wp-mail-smtp"):(0,l.__)("Please enter a valid email address","wp-mail-smtp")},verify_identity_text:function(){return"domain"===this.identity_type?(0,l.__)("Enter the domain name to verify it on Amazon SES and generate the required DNS CNAME records.","wp-mail-smtp"):(0,l.__)("Enter a valid email address. A verification email will be sent to the email address you entered.","wp-mail-smtp")},text_verify_identity_step2_email_text:function(){return(0,l.nv)((0,l.__)("Please check the inbox of %s for a confirmation email.","wp-mail-smtp"),this.verify_identity_result.value)},text_verify:function(){return"domain"===this.identity_type?(0,l.__)("Verify Domain","wp-mail-smtp"):(0,l.__)("Verify Email","wp-mail-smtp")}},data(){return{text_no_registered_identities_title:(0,l.__)("No registered domains or emails.","wp-mail-smtp"),text_no_registered_identities_content:(0,l.__)("You will not be able to send emails until you verify at least one domain or email address for the selected Amazon SES Region.","wp-mail-smtp"),text_view_dns:(0,l.__)("View DNS","wp-mail-smtp"),text_resend:(0,l.__)("Resend","wp-mail-smtp"),text_identities_table_description:(0,l.__)("Here are the domains and email addresses that have been verified and can be used as the From Email.","wp-mail-smtp"),text_verify_identity:(0,l.__)("Verify SES Identity","wp-mail-smtp"),text_add_new_identity:(0,l.__)("Add New SES Identity","wp-mail-smtp"),text_name:(0,l.__)("Name","wp-mail-smtp"),text_value:(0,l.__)("Value","wp-mail-smtp"),text_verify_identity_step2_domain_text:(0,l.nv)((0,l.__)("Please add these CNAME records to your domain's DNS settings. For information on how to add CNAME DNS records, please refer to the %1$sAmazon SES documentation%2$s.","wp-mail-smtp"),'',""),show_identity_form:!1,identity_type:"domain",identity_type_options:[{label:(0,l.__)("Verify Domain","wp-mail-smtp"),value:"domain"},{label:(0,l.__)("Verify Email Address","wp-mail-smtp"),value:"email"}],identity_value:"",verify_identity_step:1,verify_identity_result:{},loading_verify_identity:!1}},methods:{verifyIdentity:function(){if(this.loading_verify_identity)return;this.loading_verify_identity=!0;const e=this;this.$store.dispatch("$_settings/amazonSESRegisterIdentity",{value:this.identity_value,type:this.identity_type}).then((function(t){e.loading_verify_identity=!1,t.success&&t.data&&(e.verify_identity_result=t.data,e.verify_identity_step=2)}))},addNewIdentity:function(){this.show_identity_form=!0}}},Cs=ys,Ss=(0,d.A)(Cs,xs,ks,!1,null,null,null),Ms=Ss.exports,Ps={name:"WizardStepConfigureMailerAmazonSES",components:{SettingsInputText:Ue,SettingsInputSelect:vs,SettingsInputSwitch:ti,SettingsAmazonSESIdentities:Ms},data(){return{mailer:"amazonses",text_client_id_label:(0,l.__)("Access Key ID","wp-mail-smtp"),text_client_secret_label:(0,l.__)("Secret Access Key",{NODE_ENV:"production",VUE_APP_TEXTDOMAIN:"wp-mail-smtp",VUE_APP_PRODUCT_NAME:"WPMailSMTP",BASE_URL:""}.VUE_APP_TEXTclient_id),text_region_label:(0,l.__)("Region","wp-mail-smtp"),text_identities_label:(0,l.__)("SES Identities","wp-mail-smtp"),text_region_description:(0,l.__)("Please select the Amazon SES API region which is the closest to where your website is hosted. This can help to decrease network latency between your site and Amazon SES, which will speed up email sending.","wp-mail-smtp"),text_from_name_label:(0,l.__)("From Name","wp-mail-smtp"),text_force_from_name_title:(0,l.__)("Force From Name","wp-mail-smtp"),text_from_email_label:(0,l.__)("From Email","wp-mail-smtp"),text_force_from_email_title:(0,l.__)("Force From Email","wp-mail-smtp"),text_force_from_name_label:(0,l.__)("If enabled, the From Name setting above will be used for all emails, ignoring values set by other plugins.","wp-mail-smtp"),text_force_from_email_label:(0,l.__)("If enabled, the From Email setting above will be used for all emails, ignoring values set by other plugins.","wp-mail-smtp"),text_from_name_description:(0,l.__)("The name that emails are sent from.","wp-mail-smtp"),text_from_email_description:(0,l.__)("The email address that emails are sent from.","wp-mail-smtp"),text_documentation_link:(0,l.__)("Read how to set up Amazon SES","wp-mail-smtp"),text_no_ssl:(0,l.__)("Amazon SES requires an SSL certificate, and so is not currently compatible with your site. Please contact your host to request a SSL certificate, or check out ","wp-mail-smtp"),text_no_ssl_link_text:(0,l.__)("WPBeginner's tutorial on how to set up SSL","wp-mail-smtp"),text_no_ssl_diff_mailer:(0,l.__)("If you'd prefer not to set up SSL, or need an SMTP solution in the meantime, please go back and select a different mailer option.","wp-mail-smtp"),description:this.$wpms.mailer_options.amazonses.description.substr(0,this.$wpms.mailer_options.amazonses.description.indexOf(" ")),documentation_link_url:this.$getUTMUrl("https://wpmailsmtp.com/docs/how-to-set-up-the-amazon-ses-mailer-in-wp-mail-smtp/",{content:"Read how to set up Amazon SES"}),regionOptions:this.$wpms.mailer_options.amazonses.region_options||[],fetching_identities:!1,is_ssl:this.$wpms.is_ssl,field_errors:[]}},computed:{...(0,_e.YP)("$_settings",["settings.amazonses.client_id","settings.amazonses.client_secret","settings.amazonses.region","settings.mail.from_email","settings.mail.from_name","settings.mail.from_email_force","settings.mail.from_name_force"]),...(0,_e.YP)("$_settings",{identities_columns:"amazonses_identities.columns",identities:"amazonses_identities.data",display_identities:"amazonses_display_identities"}),...(0,_e.YP)("$_wizard",["blocked_step"]),is_api_auth_missing:function(){return!this.client_id||!this.client_secret||!this.region}},watch:{client_id:function(){this.getIdentitiesDelayed()},client_secret:function(){this.getIdentitiesDelayed()},region:function(){this.getIdentities()}},methods:{getIdentities:function(){this.display_identities&&(this.fetching_identities||this.client_id.length<20||this.client_secret.length<40||!this.region||(this.fetching_identities=!0,this.$store.dispatch("$_app/start_loading"),this.$store.dispatch("$_settings/getAmazonSESIdentities").then((()=>{this.fetching_identities=!1})).finally((()=>{this.$store.dispatch("$_app/stop_loading")}))))},getIdentitiesDelayed:fs()((function(){this.getIdentities()}),500),areRequiredFieldsValid(){return""===this.client_id&&this.field_errors.push("client_id"),""===this.client_secret&&this.field_errors.push("client_secret"),""===this.region&&this.field_errors.push("region"),""===this.from_email&&this.field_errors.push("from_email"),0===this.field_errors.length},removeFieldError(e){this.field_errors=this.field_errors.filter((t=>t!==e))},errorDetected(e,t){this.field_errors.push(t)}},mounted(){this.getIdentities(),this.$wpms.is_ssl||(this.blocked_step=!0)}},Es=Ps,Fs=(0,d.A)(Es,cs,ds,!1,null,"05d90eba",null),Bs=Fs.exports,Ts=function(){var e=this,t=e._self._c;return t("div",{staticClass:"wp-mail-smtp-setup-wizard-step-configure-mailer-settings wp-mail-smtp-setup-wizard-step-configure-mailer-settings-gmail"},[t("p",{staticClass:"mailer-description",domProps:{innerHTML:e._s(e.description)}}),t("p",{staticClass:"mailer-description mailer-description-links"},[t("b",[t("a",{staticClass:"wp-mail-smtp-link",attrs:{href:e.documentation_link_url,target:"_blank",rel:"noopener noreferrer"}},[e._v(e._s(e.text_documentation_link))])])]),t("div",{staticClass:"wp-mail-smtp-setup-wizard-form"},[t("div",{staticClass:"wp-mail-smtp-separator wp-mail-smtp-separator-big-margin"}),t("settings-input-switch",{attrs:{classname:"wp-mail-smtp-one-click-setup-switch",name:"one_click_setup_enabled",title:e.text_one_click_setup_title,label:e.one_click_setup_enabled?e.text_enabled:e.text_disabled,description:e.text_one_click_setup_description,show_pro:!e.is_pro},on:{clicked:e.oneClickSetupOptionClicked},model:{value:e.one_click_setup_enabled,callback:function(t){e.one_click_setup_enabled=t},expression:"one_click_setup_enabled"}}),e.one_click_setup_enabled?[e.is_license_verification_required?[t("div",{staticClass:"wp-mail-smtp-separator wp-mail-smtp-separator-big-margin"}),t("div",{staticClass:"license-form",class:{"license-form-error":e.license_error}},[t("p",{domProps:{innerHTML:e._s(e.text_license_form)}}),t("div",{staticClass:"license-control"},[t("input",{directives:[{name:"model",rawName:"v-model",value:e.license,expression:"license"}],attrs:{name:"license",type:"password",placeholder:e.text_license_input_placeholder,"aria-label":e.text_aria_label_for_license_input},domProps:{value:e.license},on:{input:function(t){t.target.composing||(e.license=t.target.value)}}}),t("button",{staticClass:"wp-mail-smtp-button wp-mail-smtp-button-success wp-mail-smtp-button-small",attrs:{type:"button"},on:{click:function(t){return t.preventDefault(),e.handleLicenseSubmit.apply(null,arguments)}}},[e._v(" "+e._s(e.text_license_button)+" ")])]),e.license_error?t("p",{staticClass:"error-message",domProps:{textContent:e._s(e.text_license_error)}}):e._e()]),t("div",{staticClass:"wp-mail-smtp-separator wp-mail-smtp-separator-big-margin"})]:e._e(),t("settings-o-auth-connection",{attrs:{hide_description:!0,mailer:e.mailer,connected_email:e.one_click_setup_connected_email_address,is_auth_required:e.is_auth_required,disabled:e.is_license_verification_required}})]:[t("div",{staticClass:"wp-mail-smtp-separator wp-mail-smtp-separator-big-margin"}),t("settings-input-text",{attrs:{name:"client_id",constant:"WPMS_GMAIL_CLIENT_ID",label:e.text_client_id_label,is_error:e.field_errors.includes("client_id")},on:{is_error_update:function(t){return e.removeFieldError("client_id")}},model:{value:e.client_id,callback:function(t){e.client_id=t},expression:"client_id"}}),t("settings-input-text",{attrs:{name:"client_secret",type:"password",constant:"WPMS_GMAIL_CLIENT_SECRET",label:e.text_client_secret_label,is_error:e.field_errors.includes("client_secret")},on:{is_error_update:function(t){return e.removeFieldError("client_secret")}},model:{value:e.client_secret,callback:function(t){e.client_secret=t},expression:"client_secret"}}),t("settings-input-text",{attrs:{value:e.redirect_uri,name:"redirect_uri",label:e.text_redirect_uri_label,copy:"",readonly:""}}),t("div",{staticClass:"wp-mail-smtp-separator wp-mail-smtp-separator-big-margin"}),t("settings-o-auth-connection",{attrs:{label:e.text_authorization_label,mailer:e.mailer,connected_email:e.connected_email_address,is_auth_required:e.is_auth_required,client_id:e.client_id,client_secret:e.client_secret}})],e.is_auth_required?e._e():t("div",{staticClass:"wp-mail-smtp-setup-wizard-form-general-settings"},[t("div",{staticClass:"wp-mail-smtp-separator wp-mail-smtp-separator-big-margin"}),t("settings-input-text",{attrs:{name:"from_name",constant:"WPMS_MAIL_FROM_NAME",label:e.text_from_name_label,description:e.text_from_name_description},model:{value:e.from_name,callback:function(t){e.from_name=t},expression:"from_name"}}),t("settings-input-switch",{attrs:{classname:"sub_setting",name:"from_name_force",constant:"WPMS_MAIL_FROM_NAME_FORCE",title:e.text_force_from_name_title,label:e.text_force_from_name_label},model:{value:e.from_name_force,callback:function(t){e.from_name_force=t},expression:"from_name_force"}}),t("settings-input-text",{attrs:{name:"from_email",type:"email",constant:"WPMS_MAIL_FROM",label:e.text_from_email_label,description:e.text_from_email_description,is_error:e.field_errors.includes("from_email")},on:{is_error_update:function(t){return e.removeFieldError("from_email")},error_detected:t=>e.errorDetected(t,"from_email")},model:{value:e.from_email,callback:function(t){e.from_email=t},expression:"from_email"}}),t("settings-input-switch",{attrs:{classname:"sub_setting",name:"from_email_force",constant:"WPMS_MAIL_FROM_FORCE",title:e.text_force_from_email_title,label:e.text_force_from_email_label},model:{value:e.from_email_force,callback:function(t){e.from_email_force=t},expression:"from_email_force"}})],1)],2)])},Is=[],Ds=function(){var e=this,t=e._self._c;return t("div",{staticClass:"settings-oauth-connection"},[e.label?t("label",{staticClass:"settings-input-label-container"},[t("span",{staticClass:"label"},[e._v(e._s(e.label))]),e.tooltip?t("settings-info-tooltip",{attrs:{content:e.tooltip}}):e._e()],1):e._e(),e.is_auth_required?t("div",{staticClass:"add-authorization-container"},[e.hide_description?e._e():t("p",{staticClass:"description",domProps:{textContent:e._s(e.text_authorization_button_description)}}),"gmail"===e.mailer&&e.gmail_one_click_setup_enabled?t("button",{staticClass:"wp-mail-smtp-one-click-sign-in-btn wp-mail-smtp-sign-in-btn__google",attrs:{type:"button",disabled:!e.are_client_details_ready||e.disabled},on:{click:function(t){return t.preventDefault(),e.authorize.apply(null,arguments)}}},[t("span",{staticClass:"wp-mail-smtp-one-click-sign-in-btn__icon"},[t("inline-svg",{staticClass:"icon",attrs:{src:i(3321),width:"46",height:"46"}})],1),t("span",{staticClass:"wp-mail-smtp-one-click-sign-in-btn__text"},[e._v(" "+e._s(e.text_google_authorization_button)+" ")])]):"outlook"===e.mailer&&e.outlook_one_click_setup_enabled?t("button",{staticClass:"wp-mail-smtp-one-click-sign-in-btn wp-mail-smtp-sign-in-btn__outlook",attrs:{type:"button",disabled:!e.are_client_details_ready||e.disabled},on:{click:function(t){return t.preventDefault(),e.authorize.apply(null,arguments)}}},[t("span",{staticClass:"wp-mail-smtp-one-click-sign-in-btn__icon"},[t("inline-svg",{staticClass:"icon",attrs:{src:i(6458),width:"46",height:"46"}})],1),t("span",{staticClass:"wp-mail-smtp-one-click-sign-in-btn__text"},[e._v(" "+e._s(e.text_outlook_authorization_button)+" ")])]):t("button",{staticClass:"wp-mail-smtp-button wp-mail-smtp-button-main wp-mail-smtp-button-small",attrs:{type:"button",disabled:!e.are_client_details_ready||e.disabled},on:{click:function(t){return t.preventDefault(),e.authorize.apply(null,arguments)}}},[e._v(" "+e._s(e.text_authorization_button)+" ")])]):t("div",{staticClass:"remove-authorization-container"},[e.connected_email?t("p",{staticClass:"description connected-as"},[t("span",{domProps:{innerHTML:e._s(e.text_connected_as_with_email)}}),e._v(" "),t("inline-svg",{staticClass:"icon",attrs:{src:i(5636),width:"16",height:"16"}})],1):e._e(),"gmail"===e.mailer?t("p",{staticClass:"description",domProps:{innerHTML:e._s(e.text_remove_authorization_button_description_google)}}):e._e(),t("p",{staticClass:"description",domProps:{innerHTML:e._s(e.text_remove_authorization_button_description)}}),t("button",{staticClass:"wp-mail-smtp-button wp-mail-smtp-button-red wp-mail-smtp-button-small",attrs:{type:"button"},on:{click:function(t){return t.preventDefault(),e.removeAuthorization.apply(null,arguments)}}},[e._v(" "+e._s(e.text_remove_authorization_button)+" ")])])])},Os=[],zs={name:"SettingsOAuthConnection",components:{SettingsInfoTooltip:Le},props:{label:String,hide_description:Boolean,mailer:String,connected_email:String,is_auth_required:Boolean,client_id:String,client_secret:String,tooltip:String,disabled:Boolean},data(){return{text_allow_button:(0,l.__)("Connect to %s","wp-mail-smtp"),text_google_authorization_button:(0,l.__)("Sign in with Google","wp-mail-smtp"),text_outlook_authorization_button:(0,l.__)("Sign in with Outlook","wp-mail-smtp"),text_authorization_button_description_general:(0,l.__)("Before continuing, you'll need to allow this plugin to send emails using your %s account.","wp-mail-smtp"),text_remove_authorization_button:(0,l.__)("Remove OAuth Connection","wp-mail-smtp"),text_remove_authorization_button_description_google:(0,l.nv)((0,l.__)("If you want to use a different From Email address you can setup a Google email alias. %1$sFollow these instructions%2$s, then select the alias in the From Email section below.","wp-mail-smtp"),'',""),text_remove_authorization_button_desc_template:(0,l.__)("Removing this OAuth connection will give you the ability to redo the OAuth connection or connect to different %s account.","wp-mail-smtp"),text_connected_as:(0,l.__)("Connected as","wp-mail-smtp")}},computed:{...(0,ae.L8)({gmail_one_click_setup_enabled:"$_settings/gmail_one_click_setup_enabled",outlook_one_click_setup_enabled:"$_settings/outlook_one_click_setup_enabled"}),are_client_details_ready:function(){return!("gmail"!==this.mailer||!this.gmail_one_click_setup_enabled)||(!("outlook"!==this.mailer||!this.outlook_one_click_setup_enabled)||!!this.client_id&&!!this.client_secret)},mailer_name:function(){let e="Google";return"outlook"===this.mailer?e="Microsoft Outlook":"zoho"===this.mailer&&(e="Zoho Mail"),e},text_authorization_button:function(){return(0,l.nv)(this.text_allow_button,this.mailer_name)},text_authorization_button_description:function(){return(0,l.nv)(this.text_authorization_button_description_general,this.mailer_name)},text_remove_authorization_button_description:function(){return(0,l.nv)(this.text_remove_authorization_button_desc_template,this.mailer_name)},text_connected_as_with_email:function(){return`${this.text_connected_as} ${this.connected_email}`}},methods:{authorize:function(){this.$store.dispatch("$_app/start_loading"),this.$store.dispatch("$_settings/getAuthUrl",this.mailer).then((function(e){e.success&&e.data.oauth_url&&(window.location.href=e.data.oauth_url)})).finally((()=>{this.$store.dispatch("$_app/stop_loading")}))},removeAuthorization:function(){this.$store.dispatch("$_app/start_loading"),this.$store.dispatch("$_settings/removeAuth",this.mailer).finally((()=>{this.$store.dispatch("$_app/stop_loading")}))},removeUrlParam:function(e,t,i){t.delete(i),e.search=t.toString(),window.history.replaceState({},document.title,e.toString())},catchAuthNotice:function(){const e=new URL(window.location.href),t=new URLSearchParams(e.search);let i="",s="",a=!1;switch(t.has("success")?(i=t.get("success"),a=!0,this.removeUrlParam(e,t,"success")):t.has("error")&&(i=t.get("error"),this.removeUrlParam(e,t,"error")),i){case"oauth_invalid_state":s=(0,l.__)("There was an error while processing the authentication request. The state key is invalid. Please try again.","wp-mail-smtp");break;case"google_no_code_scope":case"google_access_denied":case"zoho_access_denied":s=(0,l.__)("There was an error while processing the authentication request. Please try again.","wp-mail-smtp");break;case"google_no_clients":case"zoho_no_clients":case"microsoft_unsuccessful_oauth":case"google_unsuccessful_oauth":s=(0,l.__)("There was an error while processing the authentication request. Please recheck your Client ID and Client Secret and try again.","wp-mail-smtp");break;case"google_one_click_setup_unsuccessful_oauth":case"outlook_one_click_setup_unsuccessful_oauth":s=(0,l.__)("There was an error while processing the authentication request.","wp-mail-smtp");break;case"google_invalid_nonce":case"microsoft_invalid_nonce":case"zoho_invalid_nonce":s=(0,l.__)("There was an error while processing the authentication request. The nonce is invalid. Please try again.","wp-mail-smtp");break;case"microsoft_no_code":case"zoho_no_code":s=(0,l.__)("There was an error while processing the authentication request. The authorization code is missing. Please try again.","wp-mail-smtp");break;case"zoho_unsuccessful_oauth":s=(0,l.__)("There was an error while processing the authentication request. Please recheck your Region, Client ID and Client Secret and try again.","wp-mail-smtp");break;case"google_site_linked":s=(0,l.__)("You have successfully linked the current site with your Google API project. Now you can start sending emails through Gmail.","wp-mail-smtp");break;case"google_one_click_setup_site_linked":s=(0,l.__)("You have successfully connected your site with your Gmail account. Now you can start sending emails through Gmail.","wp-mail-smtp");break;case"microsoft_site_linked":s=(0,l.__)("You have successfully linked the current site with your Microsoft API project. Now you can start sending emails through Outlook.","wp-mail-smtp");break;case"outlook_one_click_setup_site_linked":s=(0,l.__)("You have successfully connected your site with your Outlook account. Now you can start sending emails through Outlook.","wp-mail-smtp");break;case"zoho_site_linked":s=(0,l.__)("You have successfully linked the current site with your Zoho Mail API project. Now you can start sending emails through Zoho Mail.","wp-mail-smtp");break}s.length>0&&this.$swal({title:a?(0,l.__)("Successful Authorization","wp-mail-smtp"):(0,l.__)("Authorization Error!","wp-mail-smtp"),text:s,width:550,showCloseButton:!0,customClass:{container:"wp-mail-smtp-swal wp-mail-smtp-swal-alert"}})}},mounted(){this.catchAuthNotice()}},Ls=zs,Rs=(0,d.A)(Ls,Ds,Os,!1,null,null,null),Ws=Rs.exports,Ns={name:"WizardStepConfigureMailerGmail",components:{SettingsInputText:Ue,SettingsInputSwitch:ti,SettingsOAuthConnection:Ws},data(){return{mailer:"gmail",text_one_click_setup_title:(0,l.__)("One-Click Setup","wp-mail-smtp"),text_one_click_setup_description:(0,l.__)("Provides a quick and easy way to connect to Google that doesn't require creating your own app.","wp-mail-smtp"),text_client_id_label:(0,l.__)("Client ID","wp-mail-smtp"),text_client_secret_label:(0,l.__)("Client Secret","wp-mail-smtp"),text_redirect_uri_label:(0,l.__)("Authorized Redirect URI","wp-mail-smtp"),text_authorization_label:(0,l.__)("Authorization","wp-mail-smtp"),text_from_name_label:(0,l.__)("From Name","wp-mail-smtp"),text_force_from_name_title:(0,l.__)("Force From Name","wp-mail-smtp"),text_from_email_label:(0,l.__)("From Email","wp-mail-smtp"),text_force_from_name_label:(0,l.__)("If enabled, the From Name setting above will be used for all emails, ignoring values set by other plugins.","wp-mail-smtp"),text_force_from_email_title:(0,l.__)("Force From Email","wp-mail-smtp"),text_force_from_email_label:(0,l.__)("If enabled, the From Email setting above will be used for all emails, ignoring values set by other plugins.","wp-mail-smtp"),text_from_name_description:(0,l.__)("The name that emails are sent from.","wp-mail-smtp"),text_from_email_description:(0,l.__)("The email address that emails are sent from. You can use only the connected email address or its alias.","wp-mail-smtp"),text_documentation_link:(0,l.__)("Read how to set up the Gmail mailer","wp-mail-smtp"),text_enabled:(0,l.__)("Enabled","wp-mail-smtp"),text_disabled:(0,l.__)("Disabled","wp-mail-smtp"),text_one_click_setup_upgrade_title:(0,l.__)("One-Click Setup for Google Mailer is a Pro Feature","wp-mail-smtp"),text_one_click_setup_upgrade_content:(0,l.__)("We're sorry, One-Click Setup for Google Mailer is not available on your plan. Please upgrade to the Pro plan to unlock all these awesome features.","wp-mail-smtp"),description:this.$wpms.mailer_options.gmail.description.substr(0,this.$wpms.mailer_options.gmail.description.indexOf(" ")),documentation_link_url:this.$getUTMUrl("https://wpmailsmtp.com/docs/how-to-set-up-the-gmail-mailer-in-wp-mail-smtp/#create-app",{content:"Read how to set up the Gmail mailer"}),redirect_uri:this.$wpms.mailer_options.gmail.redirect_uri,field_errors:[],license_verified:!1,license:"",license_error:!1,text_license_form:(0,l.__)("One-Click Setup for Google Mailer requires an active license. Verify your license to proceed with this One-Click Setup, please.","wp-mail-smtp"),text_license_input_placeholder:(0,l.__)("Paste your license key here","wp-mail-smtp"),text_aria_label_for_license_input:(0,l.__)("License key input","wp-mail-smtp"),text_license_button:(0,l.__)("Verify License Key","wp-mail-smtp"),text_license_error:(0,l.__)("The License Key format is incorrect. Please enter a valid key and try again.","wp-mail-smtp"),is_pro:this.$wpms.is_pro,one_click_setup_enabled:!1}},computed:{...(0,_e.YP)("$_settings",["settings.gmail.client_id","settings.gmail.client_secret","settings.gmail.access_token","settings.gmail.refresh_token","settings.gmail.one_click_setup_credentials","settings.mail.from_email","settings.mail.from_email_force","settings.mail.from_name","settings.mail.from_name_force"]),...(0,_e.YP)("$_wizard",["blocked_step"]),...(0,ae.L8)({is_valid_license:"$_settings/is_valid_license",one_click_setup_enabled_setting:"$_settings/gmail_one_click_setup_enabled",connected_email_address:"$_settings/gmail_email",one_click_setup_connected_email_address:"$_settings/gmail_one_click_setup_email"}),is_auth_required:function(){return this.one_click_setup_enabled?!this.one_click_setup_credentials?.key||!this.one_click_setup_credentials?.token:!this.access_token||!this.refresh_token},is_license_verification_required:function(){return!this.license_verified&&!this.is_valid_license&&this.is_auth_required}},watch:{is_auth_required:function(e){this.blocked_step=e},one_click_setup_enabled:function(e){this.is_pro&&this.$store.dispatch("$_settings/setGmailUseOneClickSetup",e)},one_click_setup_enabled_setting:function(e){this.is_pro&&(this.one_click_setup_enabled=e)}},methods:{areRequiredFieldsValid(){let e=!0;return""===this.from_email&&(e=!1,this.field_errors.push("from_email")),this.one_click_setup_enabled||(""===this.client_id&&(e=!1,this.field_errors.push("client_id")),""===this.client_secret&&(e=!1,this.field_errors.push("client_secret"))),e},removeFieldError(e){this.field_errors=this.field_errors.filter((t=>t!==e))},handleLicenseSubmit(){if(this.license_error=!1,this.license.length<16)return this.license_error=!0,!1;this.$store.dispatch("$_app/start_loading"),this.$store.dispatch("$_settings/verifyLicense",this.license).then((e=>{e.success?(this.license_verified=!0,this.$swal({title:(0,l.__)("Successful Verification!","wp-mail-smtp"),html:(0,l.__)("Now you can continue mailer configuration.","wp-mail-smtp"),width:450,showCloseButton:!0,customClass:{container:"wp-mail-smtp-swal wp-mail-smtp-swal-alert"}})):this.$swal({title:(0,l.__)("Verification Error!","wp-mail-smtp"),html:e.data,width:450,showCloseButton:!0,customClass:{container:"wp-mail-smtp-swal wp-mail-smtp-swal-alert"}})})).finally((()=>{this.$store.dispatch("$_app/stop_loading")}))},oneClickSetupOptionClicked(e){this.is_pro||(e.preventDefault(),this.oneClickSetupUpgradePopup())},oneClickSetupUpgradePopup(){var e=/(\?)/.test(this.$wpms.education.upgrade_url)?"&":"?",t=this.$wpms.education.upgrade_url+e+"utm_content="+encodeURIComponent("gmail-one-click-setup");this.$swal({title:this.text_one_click_setup_upgrade_title,html:`
`,width:550,imageUrl:i(1312),imageWidth:31,imageHeight:35,showCloseButton:!0,customClass:{container:"wp-mail-smtp-swal wp-mail-smtp-upgrade-popup"},showConfirmButton:!1})}},mounted(){this.is_auth_required&&(this.blocked_step=!0),this.is_pro&&(this.one_click_setup_enabled=this.one_click_setup_enabled_setting)}},Us=Ns,Qs=(0,d.A)(Us,Ts,Is,!1,null,null,null),Zs=Qs.exports,Gs=function(){var e=this,t=e._self._c;return t("div",{staticClass:"wp-mail-smtp-setup-wizard-step-configure-mailer-settings wp-mail-smtp-setup-wizard-step-configure-mailer-settings-outlook"},[t("p",{staticClass:"mailer-description",domProps:{innerHTML:e._s(e.description)}}),t("p",{staticClass:"mailer-description mailer-description-links"},[t("a",{staticClass:"wp-mail-smtp-link",attrs:{href:e.documentation_link_url,target:"_blank",rel:"noopener noreferrer"}},[e._v(e._s(e.text_documentation_link))])]),e.is_ssl?t("div",{staticClass:"wp-mail-smtp-setup-wizard-form"},[t("div",{staticClass:"wp-mail-smtp-separator wp-mail-smtp-separator-big-margin"}),t("settings-input-switch",{attrs:{classname:"wp-mail-smtp-one-click-setup-switch",name:"one_click_setup_enabled",title:e.text_one_click_setup_title,label:e.one_click_setup_enabled?e.text_enabled:e.text_disabled,description:e.text_one_click_setup_description},model:{value:e.one_click_setup_enabled,callback:function(t){e.one_click_setup_enabled=t},expression:"one_click_setup_enabled"}}),e.one_click_setup_enabled?[e.is_license_verification_required?[t("div",{staticClass:"wp-mail-smtp-separator wp-mail-smtp-separator-big-margin"}),t("div",{staticClass:"license-form",class:{"license-form-error":e.license_error}},[t("p",{domProps:{innerHTML:e._s(e.text_license_form)}}),t("div",{staticClass:"license-control"},[t("input",{directives:[{name:"model",rawName:"v-model",value:e.license,expression:"license"}],attrs:{name:"license",type:"password",placeholder:e.text_license_input_placeholder,"aria-label":e.text_aria_label_for_license_input},domProps:{value:e.license},on:{input:function(t){t.target.composing||(e.license=t.target.value)}}}),t("button",{staticClass:"wp-mail-smtp-button wp-mail-smtp-button-success wp-mail-smtp-button-small",attrs:{type:"button"},on:{click:function(t){return t.preventDefault(),e.handleLicenseSubmit.apply(null,arguments)}}},[e._v(" "+e._s(e.text_license_button)+" ")])]),e.license_error?t("p",{staticClass:"error-message",domProps:{textContent:e._s(e.text_license_error)}}):e._e()]),t("div",{staticClass:"wp-mail-smtp-separator wp-mail-smtp-separator-big-margin"})]:e._e(),t("settings-o-auth-connection",{attrs:{hide_description:!0,mailer:e.mailer,connected_email:e.one_click_setup_connected_email_address,is_auth_required:e.is_auth_required,disabled:e.is_license_verification_required}})]:[t("div",{staticClass:"wp-mail-smtp-separator wp-mail-smtp-separator-big-margin"}),t("settings-input-text",{attrs:{name:"client_id",constant:"WPMS_OUTLOOK_CLIENT_ID",label:e.text_client_id_label,is_error:e.field_errors.includes("client_id")},on:{is_error_update:function(t){return e.removeFieldError("client_id")}},model:{value:e.client_id,callback:function(t){e.client_id=t},expression:"client_id"}}),t("settings-input-text",{attrs:{name:"client_secret",type:"password",constant:"WPMS_OUTLOOK_CLIENT_SECRET",label:e.text_client_secret_label,is_error:e.field_errors.includes("client_secret")},on:{is_error_update:function(t){return e.removeFieldError("client_secret")}},model:{value:e.client_secret,callback:function(t){e.client_secret=t},expression:"client_secret"}}),t("settings-input-text",{attrs:{value:e.redirect_uri,name:"redirect_uri",label:e.text_redirect_uri_label,copy:"",readonly:""}}),t("div",{staticClass:"wp-mail-smtp-separator wp-mail-smtp-separator-big-margin"}),t("settings-o-auth-connection",{attrs:{label:e.text_authorization_label,mailer:e.mailer,connected_email:e.connected_email_address,is_auth_required:e.is_auth_required,client_id:e.client_id,client_secret:e.client_secret}})],e.is_auth_required?e._e():t("div",{staticClass:"wp-mail-smtp-setup-wizard-form-general-settings"},[t("div",{staticClass:"wp-mail-smtp-separator wp-mail-smtp-separator-big-margin"}),t("settings-input-text",{attrs:{name:"from_email",type:"email",constant:"WPMS_MAIL_FROM",label:e.text_from_email_label,description:e.text_from_email_description,is_error:e.field_errors.includes("from_email")},on:{is_error_update:function(t){return e.removeFieldError("from_email")},error_detected:t=>e.errorDetected(t,"from_email")},model:{value:e.from_email,callback:function(t){e.from_email=t},expression:"from_email"}}),t("settings-input-switch",{attrs:{classname:"sub_setting",name:"from_email_force",constant:"WPMS_MAIL_FROM_FORCE",title:e.text_force_from_email_title,label:e.text_force_from_email_label},model:{value:e.from_email_force,callback:function(t){e.from_email_force=t},expression:"from_email_force"}})],1)],2):t("div",{staticClass:"wp-mail-smtp-setup-wizard-form"},[t("div",{staticClass:"wp-mail-smtp-notice wp-mail-smtp-notice--error"},[t("p",[t("span",[e._v(e._s(e.text_no_ssl))]),e._v(" "),t("a",{attrs:{href:"https://www.wpbeginner.com/wp-tutorials/how-to-add-ssl-and-https-in-wordpress/",target:"_blank",rel:"noopener"}},[e._v(e._s(e.text_no_ssl_link_text))]),e._v(".")]),t("p",[e._v(e._s(e.text_no_ssl_diff_mailer))])])])])},Ys=[],Hs={name:"WizardStepConfigureMailerOutlook",components:{SettingsInputText:Ue,SettingsInputSwitch:ti,SettingsOAuthConnection:Ws},data(){return{mailer:"outlook",text_one_click_setup_title:(0,l.__)("One-Click Setup","wp-mail-smtp"),text_one_click_setup_description:(0,l.__)("Provides a quick and easy way to connect to Outlook that doesn't require creating your own app.","wp-mail-smtp"),text_client_id_label:(0,l.__)("Application ID","wp-mail-smtp"),text_client_secret_label:(0,l.__)("Application Password","wp-mail-smtp"),text_redirect_uri_label:(0,l.__)("Redirect URI","wp-mail-smtp"),text_authorization_label:(0,l.__)("Authorization","wp-mail-smtp"),text_documentation_link:(0,l.__)("Read how to set up Microsoft Outlook / 365","wp-mail-smtp"),text_enabled:(0,l.__)("Enabled","wp-mail-smtp"),text_disabled:(0,l.__)("Disabled","wp-mail-smtp"),text_no_ssl:(0,l.__)("Outlook / 365 requires an SSL certificate, and so is not currently compatible with your site. Please contact your host to request a SSL certificate, or check out ","wp-mail-smtp"),text_no_ssl_link_text:(0,l.__)("WPBeginner's tutorial on how to set up SSL","wp-mail-smtp"),text_no_ssl_diff_mailer:(0,l.__)("If you'd prefer not to set up SSL, or need an SMTP solution in the meantime, please go back and select a different mailer option.","wp-mail-smtp"),text_from_email_label:(0,l.__)("From Email","wp-mail-smtp"),text_from_email_description:(0,l.__)("The email address that emails are sent from.","wp-mail-smtp"),text_force_from_email_title:(0,l.__)("Force From Email","wp-mail-smtp"),text_force_from_email_label:(0,l.__)("If enabled, the From Email setting above will be used for all emails, ignoring values set by other plugins.","wp-mail-smtp"),description:this.$wpms.mailer_options.outlook.description.substr(0,this.$wpms.mailer_options.outlook.description.indexOf(" ")),documentation_link_url:this.$getUTMUrl("https://wpmailsmtp.com/docs/how-to-set-up-the-outlook-mailer-in-wp-mail-smtp/#microsoft-setup",{content:"Read how to set up Microsoft Outlook / 365"}),redirect_uri:this.$wpms.mailer_options.outlook.redirect_uri,field_errors:[],is_ssl:this.$wpms.is_ssl,one_click_setup_enabled:!1,license_verified:!1,license:"",license_error:!1,text_license_form:(0,l.__)("One-Click Setup for Microsoft Outlook requires an active license. Verify your license to proceed with this One-Click Setup, please.","wp-mail-smtp"),text_license_input_placeholder:(0,l.__)("Paste your license key here","wp-mail-smtp"),text_aria_label_for_license_input:(0,l.__)("License key input","wp-mail-smtp"),text_license_button:(0,l.__)("Verify License Key","wp-mail-smtp"),text_license_error:(0,l.__)("The License Key format is incorrect. Please enter a valid key and try again.","wp-mail-smtp")}},computed:{...(0,_e.YP)("$_settings",["settings.outlook.client_id","settings.outlook.client_secret","settings.outlook.access_token","settings.outlook.refresh_token","settings.outlook.one_click_setup_credentials","settings.mail.from_email","settings.mail.from_email_force"]),...(0,_e.YP)("$_wizard",["blocked_step"]),...(0,ae.L8)({is_valid_license:"$_settings/is_valid_license",one_click_setup_enabled_setting:"$_settings/outlook_one_click_setup_enabled",connected_email_address:"$_settings/outlook_email",one_click_setup_connected_email_address:"$_settings/outlook_one_click_setup_email"}),is_auth_required:function(){return this.one_click_setup_enabled?!this.one_click_setup_credentials?.access_token||!this.one_click_setup_credentials?.refresh_token:!this.access_token||!this.refresh_token},is_license_verification_required:function(){return!this.license_verified&&!this.is_valid_license&&this.is_auth_required}},watch:{is_auth_required:function(e){this.blocked_step=e},one_click_setup_enabled:function(e){this.$store.dispatch("$_settings/setOutlookUseOneClickSetup",e)},one_click_setup_enabled_setting:function(e){this.one_click_setup_enabled=e}},methods:{areRequiredFieldsValid(){let e=!0;return""===this.from_email&&(e=!1,this.field_errors.push("from_email")),this.one_click_setup_enabled||(""===this.client_id&&(e=!1,this.field_errors.push("client_id")),""===this.client_secret&&(e=!1,this.field_errors.push("client_secret"))),e},removeFieldError(e){this.field_errors=this.field_errors.filter((t=>t!==e))},errorDetected(e,t){this.field_errors.push(t)},handleLicenseSubmit(){if(this.license_error=!1,this.license.length<16)return this.license_error=!0,!1;this.$store.dispatch("$_app/start_loading"),this.$store.dispatch("$_settings/verifyLicense",this.license).then((e=>{e.success?(this.license_verified=!0,this.$swal({title:(0,l.__)("Successful Verification!","wp-mail-smtp"),html:(0,l.__)("Now you can continue mailer configuration.","wp-mail-smtp"),width:450,showCloseButton:!0,customClass:{container:"wp-mail-smtp-swal wp-mail-smtp-swal-alert"}})):this.$swal({title:(0,l.__)("Verification Error!","wp-mail-smtp"),html:e.data,width:450,showCloseButton:!0,customClass:{container:"wp-mail-smtp-swal wp-mail-smtp-swal-alert"}})})).finally((()=>{this.$store.dispatch("$_app/stop_loading")}))}},mounted(){this.is_auth_required&&(this.blocked_step=!0),this.$wpms.is_ssl||(this.blocked_step=!0),this.one_click_setup_enabled=this.one_click_setup_enabled_setting}},Vs=Hs,Ks=(0,d.A)(Vs,Gs,Ys,!1,null,"a87376ac",null),qs=Ks.exports,Js=function(){var e=this,t=e._self._c;return t("div",{staticClass:"wp-mail-smtp-setup-wizard-step-configure-mailer-settings wp-mail-smtp-setup-wizard-step-configure-mailer-settings-zoho"},[t("p",{staticClass:"mailer-description",domProps:{innerHTML:e._s(e.description)}}),t("p",{staticClass:"mailer-description mailer-description-links"},[t("a",{staticClass:"wp-mail-smtp-link",attrs:{href:e.documentation_link_url,target:"_blank",rel:"noopener noreferrer"}},[e._v(e._s(e.text_documentation_link))])]),t("div",{staticClass:"wp-mail-smtp-setup-wizard-form"},[t("settings-input-select",{attrs:{name:"domain",constant:"WPMS_ZOHO_DOMAIN",label:e.text_domain_label,options:e.domain_options,description:e.text_domain_description,is_error:e.field_errors.includes("domain")},on:{is_error_update:function(t){return e.removeFieldError("domain")}},model:{value:e.domain,callback:function(t){e.domain=t},expression:"domain"}}),t("settings-input-text",{attrs:{name:"client_id",constant:"WPMS_ZOHO_CLIENT_ID",label:e.text_client_id_label,is_error:e.field_errors.includes("client_id")},on:{is_error_update:function(t){return e.removeFieldError("client_id")}},model:{value:e.client_id,callback:function(t){e.client_id=t},expression:"client_id"}}),t("settings-input-text",{attrs:{name:"client_secret",constant:"WPMS_ZOHO_CLIENT_SECRET",type:"password",label:e.text_client_secret_label,is_error:e.field_errors.includes("client_secret")},on:{is_error_update:function(t){return e.removeFieldError("client_secret")}},model:{value:e.client_secret,callback:function(t){e.client_secret=t},expression:"client_secret"}}),t("settings-input-text",{attrs:{value:e.redirect_uri,name:"redirect_uri",label:e.text_redirect_uri_label,copy:"",readonly:""}}),t("settings-o-auth-connection",{attrs:{label:e.text_authorization_label,mailer:e.mailer,connected_email:e.connected_email_address,is_auth_required:e.is_auth_required,client_id:e.client_id,client_secret:e.client_secret}}),e.is_auth_required?e._e():t("div",[t("settings-input-text",{attrs:{name:"from_name",constant:"WPMS_MAIL_FROM_NAME",label:e.text_from_name_label,description:e.text_from_name_description},model:{value:e.from_name,callback:function(t){e.from_name=t},expression:"from_name"}}),t("settings-input-switch",{attrs:{classname:"sub_setting",name:"from_name_force",constant:"WPMS_MAIL_FROM_NAME_FORCE",title:e.text_force_from_name_title,label:e.text_force_from_name_label},model:{value:e.from_name_force,callback:function(t){e.from_name_force=t},expression:"from_name_force"}})],1)],1)])},js=[],Xs={name:"WizardStepConfigureMailerZoho",components:{SettingsInputText:Ue,SettingsInputSwitch:ti,SettingsInputSelect:vs,SettingsOAuthConnection:Ws},data(){return{mailer:"zoho",text_domain_label:(0,l.__)("Region","wp-mail-smtp"),text_domain_description:(0,l.__)("The data center location used by your Zoho account.","wp-mail-smtp"),text_client_id_label:(0,l.__)("Client ID","wp-mail-smtp"),text_client_secret_label:(0,l.__)("Client Secret","wp-mail-smtp"),text_redirect_uri_label:(0,l.__)("Redirect URI","wp-mail-smtp"),text_authorization_label:(0,l.__)("Authorization","wp-mail-smtp"),text_from_name_label:(0,l.__)("From Name","wp-mail-smtp"),text_force_from_name_title:(0,l.__)("Force From Name","wp-mail-smtp"),text_force_from_name_label:(0,l.__)("If enabled, the From Name setting above will be used for all emails, ignoring values set by other plugins.","wp-mail-smtp"),text_from_name_description:(0,l.__)("The name that emails are sent from.","wp-mail-smtp"),text_documentation_link:(0,l.__)("Read how to set up Zoho Mail","wp-mail-smtp"),description:this.$wpms.mailer_options.zoho.description.substr(0,this.$wpms.mailer_options.zoho.description.indexOf(" ")),documentation_link_url:this.$getUTMUrl("https://wpmailsmtp.com/docs/how-to-set-up-the-zoho-mailer-in-wp-mail-smtp/#zoho-account",{content:"Read how to set up Zoho Mail"}),redirect_uri:this.$wpms.mailer_options.zoho.redirect_uri,domain_options:this.$wpms.mailer_options.zoho.domain_options,field_errors:[]}},computed:{...(0,_e.YP)("$_settings",["settings.zoho.domain","settings.zoho.client_id","settings.zoho.client_secret","settings.zoho.access_token","settings.zoho.refresh_token","settings.mail.from_name","settings.mail.from_name_force"]),...(0,_e.YP)("$_wizard",["blocked_step"]),...(0,ae.L8)({connected_email_address:"$_settings/zoho_email"}),is_auth_required:function(){return!this.access_token||!this.refresh_token}},watch:{is_auth_required:function(e){this.blocked_step=e}},methods:{areRequiredFieldsValid(){let e=!0;return""===this.domain&&(e=!1,this.field_errors.push("domain")),""===this.client_id&&(e=!1,this.field_errors.push("client_id")),""===this.client_secret&&(e=!1,this.field_errors.push("client_secret")),e},removeFieldError(e){this.field_errors=this.field_errors.filter((t=>t!==e))}},mounted(){this.is_auth_required&&(this.blocked_step=!0)}},$s=Xs,ea=(0,d.A)($s,Js,js,!1,null,null,null),ta=ea.exports,ia=function(){var e=this,t=e._self._c;return t("div",{staticClass:"wp-mail-smtp-setup-wizard-step-configure-mailer-settings wp-mail-smtp-setup-wizard-step-configure-mailer-settings-elasticemail"},[t("p",{staticClass:"mailer-description",domProps:{innerHTML:e._s(e.description)}}),t("p",{staticClass:"mailer-description mailer-description-links"},[t("a",{staticClass:"wp-mail-smtp-link wp-mail-smtp-link-docs",attrs:{href:e.documentation_link_url,target:"_blank",rel:"noopener noreferrer"}},[e._v(e._s(e.text_documentation_link))])]),t("div",{staticClass:"wp-mail-smtp-setup-wizard-form"},[t("settings-input-text",{attrs:{name:"api_key",type:"password",constant:"WPMS_ELASTICEMAIL_API_KEY",label:e.text_api_key_label,description:e.text_api_key_description,is_error:e.field_errors.includes("api_key")},on:{is_error_update:function(t){return e.removeFieldError("api_key")}},model:{value:e.api_key,callback:function(t){e.api_key=t},expression:"api_key"}}),t("settings-input-text",{attrs:{name:"from_name",constant:"WPMS_MAIL_FROM_NAME",label:e.text_from_name_label,description:e.text_from_name_description},model:{value:e.from_name,callback:function(t){e.from_name=t},expression:"from_name"}}),t("settings-input-switch",{attrs:{classname:"sub_setting",name:"from_name_force",constant:"WPMS_MAIL_FROM_NAME_FORCE",title:e.text_force_from_name_title,label:e.text_force_from_name_label},model:{value:e.from_name_force,callback:function(t){e.from_name_force=t},expression:"from_name_force"}}),t("settings-input-text",{attrs:{name:"from_email",type:"email",constant:"WPMS_MAIL_FROM",label:e.text_from_email_label,description:e.text_from_email_description,is_error:e.field_errors.includes("from_email")},on:{is_error_update:function(t){return e.removeFieldError("from_email")},error_detected:t=>e.errorDetected(t,"from_email")},model:{value:e.from_email,callback:function(t){e.from_email=t},expression:"from_email"}}),t("settings-input-switch",{attrs:{classname:"sub_setting",name:"from_email_force",constant:"WPMS_MAIL_FROM_FORCE",title:e.text_force_from_email_title,label:e.text_force_from_email_label},model:{value:e.from_email_force,callback:function(t){e.from_email_force=t},expression:"from_email_force"}})],1)])},sa=[],aa={name:"WizardStepConfigureMailerElasticEmail",components:{SettingsInputText:Ue,SettingsInputSwitch:ti},data(){return{mailer:"elasticemail",text_api_key_label:(0,l.__)("API Key","wp-mail-smtp"),text_api_key_description:(0,l.nv)((0,l.__)("%1$sFollow this link%2$s to get an API Key for Elastic Email.","wp-mail-smtp"),'',""),text_from_name_label:(0,l.__)("From Name","wp-mail-smtp"),text_force_from_name_title:(0,l.__)("Force From Name","wp-mail-smtp"),text_from_email_label:(0,l.__)("From Email","wp-mail-smtp"),text_force_from_email_title:(0,l.__)("Force From Email","wp-mail-smtp"),text_force_from_name_label:(0,l.__)("If enabled, the From Name setting above will be used for all emails, ignoring values set by other plugins.","wp-mail-smtp"),text_force_from_email_label:(0,l.__)("If enabled, the From Email setting above will be used for all emails, ignoring values set by other plugins.","wp-mail-smtp"),text_from_name_description:(0,l.__)("The name that emails are sent from.","wp-mail-smtp"),text_from_email_description:(0,l.__)("The email address that emails are sent from.","wp-mail-smtp"),text_documentation_link:(0,l.__)("Read how to set up Elastic Email","wp-mail-smtp"),description:this.$wpms.mailer_options.elasticemail.description.substr(0,this.$wpms.mailer_options.elasticemail.description.lastIndexOf("
")),documentation_link_url:this.$getUTMUrl("https://wpmailsmtp.com/docs/how-to-set-up-the-elasticemail-mailer-in-wp-mail-smtp",{content:"Read how to set up Elastic Email"}),field_errors:[]}},computed:{...(0,_e.YP)("$_settings",["settings.elasticemail.api_key","settings.mail.from_email","settings.mail.from_name","settings.mail.from_email_force","settings.mail.from_name_force"])},methods:{areRequiredFieldsValid(){return""===this.api_key&&this.field_errors.push("api_key"),""===this.from_email&&this.field_errors.push("from_email"),0===this.field_errors.length},removeFieldError(e){this.field_errors=this.field_errors.filter((t=>t!==e))},errorDetected(e,t){this.field_errors.push(t)}}},na=aa,ra=(0,d.A)(na,ia,sa,!1,null,null,null),oa=ra.exports,la=function(){var e=this,t=e._self._c;return t("div",{staticClass:"wp-mail-smtp-setup-wizard-step-configure-mailer-settings wp-mail-smtp-setup-wizard-step-configure-mailer-settings-mandrill"},[t("p",{staticClass:"mailer-description",domProps:{innerHTML:e._s(e.description)}}),t("p",{staticClass:"mailer-description mailer-description-links"},[t("a",{staticClass:"wp-mail-smtp-link",attrs:{href:e.documentation_link_url,target:"_blank",rel:"noopener noreferrer"}},[e._v(e._s(e.text_documentation_link))])]),t("div",{staticClass:"wp-mail-smtp-setup-wizard-form"},[t("settings-input-text",{attrs:{name:"api_key",type:"password",constant:"WPMS_MANDRILL_API_KEY",label:e.text_api_key_label,description:e.text_api_key_description,is_error:e.field_errors.includes("api_key")},on:{is_error_update:function(t){return e.removeFieldError("api_key")}},model:{value:e.api_key,callback:function(t){e.api_key=t},expression:"api_key"}}),t("settings-input-text",{attrs:{name:"from_name",constant:"WPMS_MAIL_FROM_NAME",label:e.text_from_name_label,description:e.text_from_name_description},model:{value:e.from_name,callback:function(t){e.from_name=t},expression:"from_name"}}),t("settings-input-switch",{attrs:{classname:"sub_setting",name:"from_name_force",constant:"WPMS_MAIL_FROM_NAME_FORCE",title:e.text_force_from_name_title,label:e.text_force_from_name_label},model:{value:e.from_name_force,callback:function(t){e.from_name_force=t},expression:"from_name_force"}}),t("settings-input-text",{attrs:{name:"from_email",type:"email",constant:"WPMS_MAIL_FROM",label:e.text_from_email_label,description:e.text_from_email_description,is_error:e.field_errors.includes("from_email")},on:{is_error_update:function(t){return e.removeFieldError("from_email")},error_detected:t=>e.errorDetected(t,"from_email")},model:{value:e.from_email,callback:function(t){e.from_email=t},expression:"from_email"}}),t("settings-input-switch",{attrs:{classname:"sub_setting",name:"from_email_force",constant:"WPMS_MAIL_FROM_FORCE",title:e.text_force_from_email_title,label:e.text_force_from_email_label},model:{value:e.from_email_force,callback:function(t){e.from_email_force=t},expression:"from_email_force"}})],1)])},ma=[],pa={name:"WizardStepConfigureMailerMandrill",components:{SettingsInputText:Ue,SettingsInputSwitch:ti},data(){return{mailer:"mandrill",text_api_key_label:(0,l.__)("API Key","wp-mail-smtp"),text_api_key_description:(0,l.__)("Follow this link to get an API Key from Mandrill.","wp-mail-smtp"),text_from_name_label:(0,l.__)("From Name","wp-mail-smtp"),text_force_from_name_title:(0,l.__)("Force From Name","wp-mail-smtp"),text_force_from_name_label:(0,l.__)("If enabled, the From Name setting above will be used for all emails, ignoring values set by other plugins.","wp-mail-smtp"),text_from_name_description:(0,l.__)("The name that emails are sent from.","wp-mail-smtp"),text_from_email_label:(0,l.__)("From Email","wp-mail-smtp"),text_force_from_email_title:(0,l.__)("Force From Email","wp-mail-smtp"),text_force_from_email_label:(0,l.__)("If enabled, the From Email setting above will be used for all emails, ignoring values set by other plugins.","wp-mail-smtp"),text_from_email_description:(0,l.__)("The email address that emails are sent from.","wp-mail-smtp"),text_documentation_link:(0,l.__)("Read how to set up Mandrill","wp-mail-smtp"),description:this.$wpms.mailer_options.mandrill.description.substr(0,this.$wpms.mailer_options.mandrill.description.lastIndexOf("
")),documentation_link_url:this.$getUTMUrl("https://wpmailsmtp.com/docs/how-to-set-up-the-mandrill-mailer-in-wp-mail-smtp/",{content:"Read how to set up Mandrill"}),field_errors:[]}},computed:{...(0,_e.YP)("$_settings",["settings.mandrill.api_key","settings.mail.from_email","settings.mail.from_name","settings.mail.from_email_force","settings.mail.from_name_force"])},methods:{areRequiredFieldsValid(){return""===this.api_key&&this.field_errors.push("api_key"),""===this.from_email&&this.field_errors.push("from_email"),0===this.field_errors.length},removeFieldError(e){this.field_errors=this.field_errors.filter((t=>t!==e))},errorDetected(e,t){this.field_errors.push(t)}}},_a=pa,ca=(0,d.A)(_a,la,ma,!1,null,null,null),da=ca.exports,ua=function(){var e=this,t=e._self._c;return t("div",{staticClass:"wp-mail-smtp-setup-wizard-step-configure-mailer-settings wp-mail-smtp-setup-wizard-step-configure-mailer-settings-resend"},[t("p",{staticClass:"mailer-description",domProps:{innerHTML:e._s(e.description)}}),t("p",{staticClass:"mailer-description mailer-description-links"},[t("a",{staticClass:"wp-mail-smtp-link",attrs:{href:e.documentation_link_url,target:"_blank",rel:"noopener noreferrer"}},[e._v(e._s(e.text_documentation_link))])]),t("div",{staticClass:"wp-mail-smtp-setup-wizard-form"},[t("settings-input-text",{attrs:{name:"api_key",type:"password",constant:"WPMS_RESEND_API_KEY",label:e.text_api_key_label,description:e.text_api_key_description,is_error:e.field_errors.includes("api_key")},on:{is_error_update:function(t){return e.removeFieldError("api_key")}},model:{value:e.api_key,callback:function(t){e.api_key=t},expression:"api_key"}}),t("settings-input-text",{attrs:{name:"from_name",constant:"WPMS_MAIL_FROM_NAME",label:e.text_from_name_label,description:e.text_from_name_description},model:{value:e.from_name,callback:function(t){e.from_name=t},expression:"from_name"}}),t("settings-input-switch",{attrs:{classname:"sub_setting",name:"from_name_force",constant:"WPMS_MAIL_FROM_NAME_FORCE",title:e.text_force_from_name_title,label:e.text_force_from_name_label},model:{value:e.from_name_force,callback:function(t){e.from_name_force=t},expression:"from_name_force"}}),t("settings-input-text",{attrs:{name:"from_email",type:"email",constant:"WPMS_MAIL_FROM",label:e.text_from_email_label,description:e.text_from_email_description,is_error:e.field_errors.includes("from_email")},on:{is_error_update:function(t){return e.removeFieldError("from_email")},error_detected:t=>e.errorDetected(t,"from_email")},model:{value:e.from_email,callback:function(t){e.from_email=t},expression:"from_email"}}),t("settings-input-switch",{attrs:{classname:"sub_setting",name:"from_email_force",constant:"WPMS_MAIL_FROM_FORCE",title:e.text_force_from_email_title,label:e.text_force_from_email_label},model:{value:e.from_email_force,callback:function(t){e.from_email_force=t},expression:"from_email_force"}})],1)])},fa=[],ha={name:"WizardStepConfigureMailerResend",components:{SettingsInputText:Ue,SettingsInputSwitch:ti},data(){return{mailer:"resend",text_api_key_label:(0,l.__)("API Key","wp-mail-smtp"),text_api_key_description:(0,l.nv)((0,l.__)("%1$sFollow this link%2$s to get an API Key for Resend.","wp-mail-smtp"),'',""),text_from_name_label:(0,l.__)("From Name","wp-mail-smtp"),text_force_from_name_title:(0,l.__)("Force From Name","wp-mail-smtp"),text_from_email_label:(0,l.__)("From Email","wp-mail-smtp"),text_force_from_email_title:(0,l.__)("Force From Email","wp-mail-smtp"),text_force_from_name_label:(0,l.__)("If enabled, the From Name setting above will be used for all emails, ignoring values set by other plugins.","wp-mail-smtp"),text_force_from_email_label:(0,l.__)("If enabled, the From Email setting above will be used for all emails, ignoring values set by other plugins.","wp-mail-smtp"),text_from_name_description:(0,l.__)("The name that emails are sent from.","wp-mail-smtp"),text_from_email_description:(0,l.__)("The email address that emails are sent from.","wp-mail-smtp"),text_documentation_link:(0,l.__)("Read how to set up Resend","wp-mail-smtp"),description:this.$wpms.mailer_options.resend.description.substr(0,this.$wpms.mailer_options.resend.description.indexOf(" ")),documentation_link_url:this.$getUTMUrl("https://wpmailsmtp.com/docs/how-to-set-up-the-resend-mailer-in-wp-mail-smtp/",{content:"Read how to set up Resend"}),field_errors:[]}},computed:{...(0,_e.YP)("$_settings",["settings.resend.api_key","settings.mail.from_email","settings.mail.from_name","settings.mail.from_email_force","settings.mail.from_name_force"])},methods:{areRequiredFieldsValid(){return""===this.api_key&&this.field_errors.push("api_key"),""===this.from_email&&this.field_errors.push("from_email"),0===this.field_errors.length},removeFieldError(e){this.field_errors=this.field_errors.filter((t=>t!==e))},errorDetected(e,t){this.field_errors.push(t)}}},ga=ha,wa=(0,d.A)(ga,ua,fa,!1,null,null,null),Aa=wa.exports,ba=function(){var e=this,t=e._self._c;return t("div",{staticClass:"wp-mail-smtp-setup-wizard-step wp-mail-smtp-setup-wizard-step-configure-email-logs"},[t("div",{staticClass:"wp-mail-smtp-setup-wizard-content-container"},[t("div",{staticClass:"wp-mail-smtp-configure-email-logs-header"},[t("the-wizard-step-counter"),t("content-header",{attrs:{title:e.text_header_title,subtitle:e.text_header_subtitle}})],1),t("div",{staticClass:"wp-mail-smtp-plugin-configure-email-logs"},[t("settings-input-long-checkbox",{attrs:{name:"log_email_content",label:e.text_log_email_content,description:e.text_log_email_content_desc},model:{value:e.log_email_content,callback:function(t){e.log_email_content=t},expression:"log_email_content"}}),t("settings-input-long-checkbox",{attrs:{name:"save_attachments",label:e.text_save_attachments,description:e.text_save_attachments_desc},model:{value:e.save_attachments,callback:function(t){e.save_attachments=t},expression:"save_attachments"}}),t("settings-input-long-checkbox",{attrs:{name:"open_email_tracking",label:e.text_open_email_tracking,description:e.text_open_email_tracking_desc},model:{value:e.open_email_tracking,callback:function(t){e.open_email_tracking=t},expression:"open_email_tracking"}}),t("settings-input-long-checkbox",{attrs:{name:"click_link_tracking",label:e.text_click_link_tracking,description:e.text_click_link_tracking_desc},model:{value:e.click_link_tracking,callback:function(t){e.click_link_tracking=t},expression:"click_link_tracking"}})],1)]),t("div",{staticClass:"wp-mail-smtp-separator wp-mail-smtp-separator-no-margin"}),t("div",{staticClass:"wp-mail-smtp-setup-wizard-step-footer"},[t("a",{attrs:{href:"#"},on:{click:function(t){return t.preventDefault(),e.previousStep.apply(null,arguments)}}},[t("span",{staticClass:"text-with-arrow text-with-arrow-left"},[t("inline-svg",{staticClass:"icon",attrs:{src:i(9004),width:"16",height:"18"}}),e._v(e._s(e.text_previous_step)+" ")],1)]),t("div",{staticClass:"wp-mail-smtp-setup-wizard-step-footer-buttons"},[t("button",{staticClass:"wp-mail-smtp-button wp-mail-smtp-button-main",attrs:{type:"submit",name:"next_step"},on:{click:function(t){return t.preventDefault(),e.handleSubmit.apply(null,arguments)}}},[t("span",{staticClass:"text-with-arrow text-with-arrow-right"},[e._v(" "+e._s(e.text_save)+" "),t("inline-svg",{staticClass:"icon",attrs:{src:i(953),width:"16",height:"19"}})],1)])])])])},va=[],xa={name:"WizardStepConfigureEmailLogs",components:{ContentHeader:f,TheWizardStepCounter:j,SettingsInputLongCheckbox:ke},data(){return{text_header_title:(0,l.__)("Configure Email Logs","wp-mail-smtp"),text_header_subtitle:(0,l.__)("Enable these powerful logging features for more control of your WordPress emails.","wp-mail-smtp"),text_save:(0,l.__)("Save and Continue","wp-mail-smtp"),text_previous_step:(0,l.__)("Previous Step","wp-mail-smtp"),text_log_email_content:(0,l.__)("Store the content for all sent emails","wp-mail-smtp"),text_log_email_content_desc:(0,l.__)("This option must be enabled if you'd like to be able to resend emails. Please be aware that all email content will be stored in your WordPress database. This may include sensitive data, passwords, and personal details.","wp-mail-smtp"),text_save_attachments:(0,l.__)("Save file attachments sent from WordPress","wp-mail-smtp"),text_save_attachments_desc:(0,l.__)("All file attachments sent from your site will be saved to the WordPress Uploads folder. Please note that this may reduce available disk space on your server.","wp-mail-smtp"),text_open_email_tracking:(0,l.__)("Track when an email is opened","wp-mail-smtp"),text_open_email_tracking_desc:(0,l.__)("See which emails were opened by the recipients. Email open tracking works with emails that are sent in HTML format.","wp-mail-smtp"),text_click_link_tracking:(0,l.__)("Track when a link in an email is clicked","wp-mail-smtp"),text_click_link_tracking_desc:(0,l.__)("See which links were clicked in emails sent from your WordPress site. Click tracking works with emails that are sent in HTML format.","wp-mail-smtp")}},computed:{...(0,_e.YP)("$_settings",["settings.logs.log_email_content","settings.logs.save_attachments","settings.logs.open_email_tracking","settings.logs.click_link_tracking"])},methods:{handleSubmit(){this.$store.dispatch("$_app/start_loading");let e={value:{logs:{log_email_content:this.log_email_content,save_attachments:this.save_attachments,open_email_tracking:this.open_email_tracking,click_link_tracking:this.click_link_tracking}}};this.$store.dispatch("$_settings/updateSettings",e).then((e=>{e.success?this.nextStep():this.$wpms_error_toast({})})).finally((()=>{this.$store.dispatch("$_app/stop_loading")}))},previousStep(){this.$previous_step()},nextStep(){this.$next_step()}}},ka=xa,ya=(0,d.A)(ka,ba,va,!1,null,null,null),Ca=ya.exports,Sa=new n.Ay({routes:[{path:"*",redirect:"/"},{path:"/",name:"welcome",component:C},{path:"/step",name:"step",component:L,children:[{path:"import",name:"import_step",component:te},{path:"choose_mailer",name:"choose_mailer_step",component:le},{path:"configure_mailer",name:"configure_mailer_step",component:fe,children:[{path:"smtp",name:"configure_mailer_step_smtp",component:ni},{path:"sendlayer",name:"configure_mailer_step_sendlayer",component:_i},{path:"smtpcom",name:"configure_mailer_step_smtpcom",component:gi},{path:"sendinblue",name:"configure_mailer_step_sendinblue",component:ki},{path:"mailersend",name:"configure_mailer_step_mailersend",component:Ei},{path:"mailgun",name:"configure_mailer_step_mailgun",component:Oi},{path:"mailjet",name:"configure_mailer_step_mailjet",component:Ui},{path:"mandrill",name:"configure_mailer_step_mandrill",component:da},{path:"sendgrid",name:"configure_mailer_step_sendgrid",component:Vi},{path:"smtp2go",name:"configure_mailer_step_smtp2go",component:$i},{path:"sparkpost",name:"configure_mailer_step_sparkpost",component:ns},{path:"postmark",name:"configure_mailer_step_postmark",component:_s},{path:"amazoneses",name:"configure_mailer_step_amazonses",component:Bs},{path:"gmail",name:"configure_mailer_step_gmail",component:Zs},{path:"outlook",name:"configure_mailer_step_outlook",component:qs},{path:"zoho",name:"configure_mailer_step_zoho",component:ta},{path:"elasticemail",name:"configure_mailer_step_elasticemail",component:oa},{path:"resend",name:"configure_mailer_step_resend",component:Aa}]},{path:"plugin_features",name:"plugin_features_step",component:Me},{path:"configure_email_logs",name:"configure_email_logs_step",component:Ca},{path:"help_improve",name:"help_improve_step",component:je},{path:"license",name:"license_step",component:nt},{path:"check_configuration",name:"check_configuration_step",component:_t},{path:"successful_configuration",name:"check_configuration_step_success",component:Et},{path:"failed_configuration",name:"check_configuration_step_failure",component:Ot}]}],scrollBehavior(){return{x:0,y:0}}}),Ma={name:"SetupWizardApp",router:Sa,computed:{...(0,ae.L8)({blocked:"$_app/blocked",loading:"$_app/loading"})}},Pa=Ma,Ea=(0,d.A)(Pa,s,a,!1,null,null,null),Fa=Ea.exports,Ba=i(5471),Ta=i(1823);const Ia={install(e){window.wp_mail_smtp_vue&&(e.prototype.$wpms=window.wp_mail_smtp_vue),e.prototype.$isPro=Da,e.prototype.$addQueryArg=Oa,e.prototype.$getUTMUrl=za}};function Da(){return window.wp_mail_smtp_vue.is_pro}function Oa(e,t,i){var s=new RegExp("([?&])"+t+"=.*?(&|#|$)","i");if(e.match(s))return e.replace(s,"$1"+t+"="+i+"$2");var a="";-1!==e.indexOf("#")&&(a=e.replace(/.*#/,"#"),e=e.replace(/#.*/,""));var n=-1!==e.indexOf("?")?"&":"?";return e+n+t+"="+i+a}function za(e,t){t={source:"WordPress",medium:"setup-wizard",campaign:Da()?"plugin":"liteplugin",content:"general",...t};for(const[i,s]of Object.entries(t))e=Oa(e,`utm_${i}`,encodeURIComponent(s));return e}var La=Ia;const Ra={install(e){e.prototype.$next_step=function(t=0){const i=e.prototype.$wizard_steps.findIndex((e=>this.$route.name.includes(e)))+1+t;this.$router.push({name:e.prototype.$wizard_steps[i]})},e.prototype.$previous_step=function(t=0){let i="welcome";const s=e.prototype.$wizard_steps.findIndex((e=>this.$route.name.includes(e)))-1-t;s>=0&&(i=e.prototype.$wizard_steps[s]),this.$router.push({name:i})},e.prototype.$swal&&(e.prototype.$wpms_success_toast=function(t){let{animation:i=!1,toast:s=!0,position:a="top-end",showConfirmButton:n=!1,icon:r="success",timer:o=3e3,showCloseButton:m=!0,title:p=(0,l.__)("Settings Updated","wp-mail-smtp"),showCancelButton:_=!1,confirmButtonText:c="",cancelButtonText:d="",text:u=""}=t;return e.prototype.$swal({animation:i,toast:s,position:a,showConfirmButton:n,icon:r,showCloseButton:m,title:p,timer:o,showCancelButton:_,confirmButtonText:c,cancelButtonText:d,text:u})},e.prototype.$wpms_error_toast=function(t){let{animation:i=!1,toast:s=!0,position:a="top-end",showConfirmButton:n=!1,icon:r="error",showCloseButton:o=!0,title:m=(0,l.__)("Could Not Save Changes","wp-mail-smtp"),text:p=""}=t;return e.prototype.$swal({animation:i,toast:s,position:a,showConfirmButton:n,icon:r,showCloseButton:o,title:m,text:p,onOpen:function(){e.prototype.$swal.hideLoading()}})},e.prototype.$wpms_error_modal=function(t){let{position:i="center",width:s=650,showConfirmButton:a=!0,confirmButtonText:n=(0,l.__)("Return to Mailer Settings","wp-mail-smtp"),customClass:r={container:"wp-mail-smtp-swal wp-mail-smtp-swal-error"},showCloseButton:o=!0,title:m=(0,l.__)("Whoops, we found an issue!","wp-mail-smtp"),subtitle:p=(0,l.__)("It looks like something went wrong...","wp-mail-smtp"),detailedError:_=""}=t;return e.prototype.$swal({position:i,width:s,showConfirmButton:a,confirmButtonText:n,customClass:r,showCloseButton:o,title:m,html:`\n\t\t\t\t\t\t
${p}
\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t
${(0,l.__)("Error Message:","wp-mail-smtp")}
\n\t\t\t\t\t\t\t
${_}
\n\t\t\t\t\t\t
\n\t\t\t\t\t`,allowEscapeKey:!1,allowOutsideClick:!1,onOpen:function(){e.prototype.$swal.hideLoading()}})},e.prototype.$required_fields_modal=function(){return e.prototype.$swal({position:"center",width:450,showConfirmButton:!0,confirmButtonText:(0,l.__)("OK","wp-mail-smtp"),customClass:{container:"wp-mail-smtp-swal wp-mail-smtp-swal-alert"},showCloseButton:!0,title:(0,l.__)("Heads up!","wp-mail-smtp"),text:(0,l.__)("Please fill out all the required fields to continue.","wp-mail-smtp"),allowEscapeKey:!1,allowOutsideClick:!1})})}};var Wa=Ra,Na=i(4335);const Ua=function(e,t){return new Promise(((i,s)=>{let a=new FormData;a.append("action","wp_mail_smtp_vue_install_plugin"),a.append("nonce",Ba.Ay.prototype.$wpms.nonce),a.append("slug",t),Na.A.post(Ba.Ay.prototype.$wpms.ajax_url,a).then((t=>{if(t.data.success)e.commit("PLUGIN_INSTALLED",t.data);else{let e="";tt()(t.data,"data[0].message")?e=t.data.data[0].message:tt()(t.data,"data")&&(e=t.data.data),Ba.Ay.prototype.$wpms_error_modal({subtitle:(0,l.__)("It looks like the plugin installation failed!","wp-mail-smtp"),detailedError:e})}i(t.data)})).catch((function(e){if(s(e),e.response){const t=e.response;return Ba.Ay.prototype.$wpms_error_modal({subtitle:(0,l.__)("It looks like we can't install the plugin.","wp-mail-smtp"),detailedError:(0,l.nv)((0,l.__)("%1$s, %2$s","wp-mail-smtp"),t.status,t.statusText)})}Ba.Ay.prototype.$wpms_error_toast({title:(0,l.__)("You appear to be offline. Plugin not installed.","wp-mail-smtp")})}))}))},Qa=function(e){return new Promise(((t,i)=>{let s=new FormData;s.append("action","wp_mail_smtp_vue_get_partner_plugins_info"),s.append("nonce",Ba.Ay.prototype.$wpms.nonce),Na.A.post(Ba.Ay.prototype.$wpms.ajax_url,s).then((i=>{i.data.success?e.commit("PLUGINS_FETCHED",i.data):Ba.Ay.prototype.$wpms_error_toast({title:(0,l.__)("Can't fetch plugins information.","wp-mail-smtp")}),t(i.data)})).catch((function(e){if(i(e),e.response){const t=e.response;return Ba.Ay.prototype.$wpms_error_modal({subtitle:(0,l.__)("It looks like we can't fetch plugins information.","wp-mail-smtp"),detailedError:(0,l.nv)((0,l.__)("%1$s, %2$s","wp-mail-smtp"),t.status,t.statusText)})}Ba.Ay.prototype.$wpms_error_toast({title:(0,l.__)("You appear to be offline. Plugin information not retrieved.","wp-mail-smtp")})}))}))};var Za={installPlugin:Ua,fetchPlugins:Qa};const Ga=function(e,t){return Za.installPlugin(e,t)},Ya=function(e){return Za.fetchPlugins(e)};var Ha={installPlugin:Ga,getPlugins:Ya};const Va=e=>e.plugins,Ka=e=>e.plugins.filter((e=>"wpforms-lite"!==e.slug)),qa=e=>e.contact_form_plugin_already_installed;var Ja={getField:_e.VI,plugins:Va,partner_plugins:Ka,contact_form_plugin_already_installed:qa};const ja=(e,t)=>{e.plugins.map((i=>(i.slug===t.data.slug&&(i.is_installed=t.data.is_installed,i.is_activated=t.data.is_activated),"wpforms-lite"===t.data.slug&&(e.contact_form_plugin_already_installed=!0),i)))},Xa=(e,t)=>{e.plugins=t.data.plugins,e.contact_form_plugin_already_installed=t.data.contact_form_plugin_already_installed};var $a={updateField:_e.cP,PLUGIN_INSTALLED:ja,PLUGINS_FETCHED:Xa};const en={plugins:[],contact_form_plugin_already_installed:!1,smart_contact_form_setting:!0};var tn={namespaced:!0,state:en,actions:Ha,getters:Ja,mutations:$a};const sn=e=>new Promise(((t,i)=>{let s=new FormData;s.append("action","wp_mail_smtp_vue_get_settings"),s.append("nonce",Ba.Ay.prototype.$wpms.nonce),Na.A.post(Ba.Ay.prototype.$wpms.ajax_url,s).then((e=>{e.data.success?t(e.data):i(e.data)})).catch((function(t){if(e.dispatch("$_app/block",!1,{root:!0}),t.response){const e=t.response;return Ba.Ay.prototype.$wpms_error_modal({subtitle:(0,l.__)("It looks like we can't load the settings.","wp-mail-smtp"),detailedError:(0,l.nv)((0,l.__)("%1$s, %2$s","wp-mail-smtp"),e.status,e.statusText)})}Ba.Ay.prototype.$wpms_error_toast({title:(0,l.__)("You appear to be offline.","wp-mail-smtp")})}))})),an=(e,t)=>new Promise(((e,i)=>{let s=new FormData;s.append("action","wp_mail_smtp_vue_get_amazon_ses_identities"),s.append("nonce",Ba.Ay.prototype.$wpms.nonce),!1!==t&&s.append("value",JSON.stringify(t)),Na.A.post(Ba.Ay.prototype.$wpms.ajax_url,s).then((t=>{t.data.success?e(t.data):i(t.data)})).catch((function(e){if(e.response){const t=e.response;return Ba.Ay.prototype.$wpms_error_modal({subtitle:(0,l.__)("It looks like we can't retrieve Amazon SES Identities.","wp-mail-smtp"),detailedError:(0,l.nv)((0,l.__)("%1$s, %2$s","wp-mail-smtp"),t.status,t.statusText)})}Ba.Ay.prototype.$wpms_error_toast({title:(0,l.__)("Can't retrieve Amazon SES Identities.","wp-mail-smtp")})}))})),nn=(e,t)=>new Promise(((e,i)=>{let s=new FormData;s.append("action","wp_mail_smtp_vue_amazon_ses_identity_registration"),s.append("nonce",Ba.Ay.prototype.$wpms.nonce),!1!==t.value&&s.append("value",t.value),!1!==t.value&&s.append("type",t.type),Na.A.post(Ba.Ay.prototype.$wpms.ajax_url,s).then((t=>{t.data.success?e(t.data):i(t.data)})).catch((function(e){if(e.response){const t=e.response;return Ba.Ay.prototype.$wpms_error_modal({subtitle:(0,l.__)("It looks like we can't register the Amazon SES Identity.","wp-mail-smtp"),detailedError:(0,l.nv)((0,l.__)("%1$s, %2$s","wp-mail-smtp"),t.status,t.statusText)})}Ba.Ay.prototype.$wpms_error_toast({title:(0,l.__)("Can't register the Amazon SES Identity","wp-mail-smtp")})}))})),rn=(e,t)=>new Promise((e=>{let i=new FormData;i.append("action","wp_mail_smtp_vue_update_settings"),i.append("nonce",Ba.Ay.prototype.$wpms.nonce),void 0!==t.overwrite&&i.append("overwrite",t.overwrite),!1!==t.value&&i.append("value",JSON.stringify(t.value)),Na.A.post(Ba.Ay.prototype.$wpms.ajax_url,i).then((t=>{e(t.data)})).catch((function(e){if(e.response){const t=e.response;return Ba.Ay.prototype.$wpms_error_modal({subtitle:(0,l.__)("It looks like we can't save the settings.","wp-mail-smtp"),detailedError:(0,l.nv)((0,l.__)("%1$s, %2$s","wp-mail-smtp"),t.status,t.statusText)})}Ba.Ay.prototype.$wpms_error_toast({title:(0,l.__)("Network error encountered. Settings not saved.","wp-mail-smtp")})}))})),on=(e,t)=>new Promise((e=>{let i=new FormData;i.append("action","wp_mail_smtp_vue_import_settings"),i.append("nonce",Ba.Ay.prototype.$wpms.nonce),!1!==t.value&&i.append("value",t.value),Na.A.post(Ba.Ay.prototype.$wpms.ajax_url,i).then((t=>{e(t.data)})).catch((function(e){if(e.response){const t=e.response;return Ba.Ay.prototype.$wpms_error_modal({subtitle:(0,l.__)("It looks like we can't import the plugin settings.","wp-mail-smtp"),detailedError:(0,l.nv)((0,l.__)("%1$s, %2$s","wp-mail-smtp"),t.status,t.statusText)})}Ba.Ay.prototype.$wpms_error_toast({title:(0,l.__)("Network error encountered. SMTP plugin import failed!","wp-mail-smtp")})}))})),ln=function(e,t){return new Promise(((i,s)=>{let a=new FormData;a.append("action","wp_mail_smtp_vue_get_oauth_url"),a.append("nonce",Ba.Ay.prototype.$wpms.nonce),!1!==e&&a.append("mailer",e),!1!==t&&a.append("settings",JSON.stringify(t)),Na.A.post(Ba.Ay.prototype.$wpms.ajax_url,a).then((e=>{e.data.success?i(e.data):s(e.data)})).catch((function(e){if(e.response){const t=e.response;return Ba.Ay.prototype.$wpms_error_modal({subtitle:(0,l.__)("It looks like we can't load authentication details.","wp-mail-smtp"),detailedError:(0,l.nv)((0,l.__)("%1$s, %2$s","wp-mail-smtp"),t.status,t.statusText)})}Ba.Ay.prototype.$wpms_error_toast({title:(0,l.__)("You appear to be offline.","wp-mail-smtp")})}))}))},mn=function(e){return new Promise(((t,i)=>{let s=new FormData;s.append("action","wp_mail_smtp_vue_remove_oauth_connection"),s.append("nonce",Ba.Ay.prototype.$wpms.nonce),!1!==e&&s.append("mailer",e),Na.A.post(Ba.Ay.prototype.$wpms.ajax_url,s).then((e=>{e.data.success?t(e.data):i(e.data)})).catch((function(e){if(e.response){const t=e.response;return Ba.Ay.prototype.$wpms_error_modal({subtitle:(0,l.__)("It looks like we can't remove OAuth connection.","wp-mail-smtp"),detailedError:(0,l.nv)((0,l.__)("%1$s, %2$s","wp-mail-smtp"),t.status,t.statusText)})}Ba.Ay.prototype.$wpms_error_toast({title:(0,l.__)("You appear to be offline.","wp-mail-smtp")})}))}))},pn=function(e){return new Promise(((t,i)=>{let s=new FormData;e?s.append("action","wp_mail_smtp_vue_remove_gmail_one_click_setup_oauth_connection"):s.append("action","wp_mail_smtp_vue_remove_oauth_connection"),s.append("nonce",Ba.Ay.prototype.$wpms.nonce),s.append("mailer","gmail"),Na.A.post(Ba.Ay.prototype.$wpms.ajax_url,s).then((e=>{e.data.success?t(e.data):i(e.data)})).catch((function(e){if(e.response){const t=e.response;return Ba.Ay.prototype.$wpms_error_modal({subtitle:(0,l.__)("It looks like we can't remove OAuth connection.","wp-mail-smtp"),detailedError:(0,l.nv)((0,l.__)("%1$s, %2$s","wp-mail-smtp"),t.status,t.statusText)})}Ba.Ay.prototype.$wpms_error_toast({title:(0,l.__)("You appear to be offline.","wp-mail-smtp")})}))}))},_n=function(e){return new Promise(((t,i)=>{let s=new FormData;e?s.append("action","wp_mail_smtp_vue_remove_outlook_one_click_setup_oauth_connection"):s.append("action","wp_mail_smtp_vue_remove_oauth_connection"),s.append("nonce",Ba.Ay.prototype.$wpms.nonce),s.append("mailer","outlook"),Na.A.post(Ba.Ay.prototype.$wpms.ajax_url,s).then((e=>{e.data.success?t(e.data):i(e.data)})).catch((function(e){if(e.response){const t=e.response;return Ba.Ay.prototype.$wpms_error_modal({subtitle:(0,l.__)("It looks like we can't remove OAuth connection.","wp-mail-smtp"),detailedError:(0,l.nv)((0,l.__)("%1$s, %2$s","wp-mail-smtp"),t.status,t.statusText)})}Ba.Ay.prototype.$wpms_error_toast({title:(0,l.__)("You appear to be offline.","wp-mail-smtp")})}))}))},cn=function(e){return new Promise(((t,i)=>{let s=new FormData;s.append("action","wp_mail_smtp_vue_get_connected_data"),s.append("nonce",Ba.Ay.prototype.$wpms.nonce),!1!==e&&s.append("mailer",e),Na.A.post(Ba.Ay.prototype.$wpms.ajax_url,s).then((e=>{e.data.success?t(e.data):i(e.data)})).catch((function(e){if(e.response){const t=e.response;return Ba.Ay.prototype.$wpms_error_modal({subtitle:(0,l.__)("It looks like we can't load oAuth connected data.","wp-mail-smtp"),detailedError:(0,l.nv)((0,l.__)("%1$s, %2$s","wp-mail-smtp"),t.status,t.statusText)})}Ba.Ay.prototype.$wpms_error_toast({title:(0,l.__)("You appear to be offline.","wp-mail-smtp")})}))}))},dn=function(e){return new Promise((t=>{let i=new FormData;i.append("action","wp_mail_smtp_vue_subscribe_to_newsletter"),i.append("nonce",Ba.Ay.prototype.$wpms.nonce),i.append("email",e),Na.A.post(Ba.Ay.prototype.$wpms.ajax_url,i).then((e=>{t(e.data)}))}))},un=function(e){return new Promise((t=>{let i=new FormData;i.append("action","wp_mail_smtp_vue_verify_license_key"),i.append("nonce",Ba.Ay.prototype.$wpms.nonce),i.append("license_key",e),Na.A.post(Ba.Ay.prototype.$wpms.ajax_url,i).then((e=>{t(e.data)}))}))},fn=function(e){return new Promise((t=>{let i=new FormData;i.append("action","wp_mail_smtp_vue_upgrade_plugin"),i.append("nonce",Ba.Ay.prototype.$wpms.nonce),i.append("license_key",e),Na.A.post(Ba.Ay.prototype.$wpms.ajax_url,i).then((e=>{t(e.data)}))}))};var hn={fetchSettings:sn,saveSettings:rn,importOtherPluginSettings:on,fetchAmazonSESIdentities:an,amazonSESRegisterIdentity:nn,getAuthRedirect:ln,removeAuth:mn,removeGmailAuth:pn,removeOutlookAuth:_n,getConnectedData:cn,subscribeToNewsletter:dn,verifyLicense:un,upgradePlugin:fn};const gn=e=>hn.fetchSettings(e).then((t=>{e.commit("SETTINGS_UPDATED",t.data)})).catch((e=>{if(e.data)return Ba.Ay.prototype.$wpms_error_modal({subtitle:(0,l.__)("It looks like we can't load existing settings.","wp-mail-smtp"),detailedError:e.data})})),wn=e=>{const t=e.getters.settings.amazonses;if(0!==Object.keys(t).length)return hn.fetchAmazonSESIdentities(e,t).then((t=>{e.commit("AMAZONSES_IDENTITIES_UPDATED",t),Ba.Ay.swal.close()})).catch((e=>{Ba.Ay.prototype.$wpms_error_modal({subtitle:(0,l.__)("It looks like we can't retrieve the Amazon SES Identities.","wp-mail-smtp"),detailedError:e.data?e.data:""})}))},An=(e,t)=>hn.amazonSESRegisterIdentity(e,t).catch((e=>{Ba.Ay.prototype.$wpms_error_modal({subtitle:(0,l.__)("It looks like we can't register the Amazon SES Identity.","wp-mail-smtp"),detailedError:e.data})})),bn=(e,t)=>{e.commit("MAILER_UPDATE",t)},vn=(e,t)=>new Promise((function(i){e.commit("LOGS_UPDATE",t),i({success:!0})})),xn=(e,t)=>new Promise((function(i){e.commit("SUMMARY_REPORT_EMAIL_UPDATE",t),i({success:!0})})),kn=(e,t)=>{e.commit("SETTINGS_SAVE_START");let i=hn.saveSettings(e,t);return i.then((function(){e.commit("SETTINGS_SAVE_END")})),i},yn=e=>{const t=e.getters.settings;e.commit("SETTINGS_SAVE_START");let i=hn.saveSettings(e,{value:t});return i.then((function(){e.commit("SETTINGS_SAVE_END")})),i},Cn=(e,t)=>(e.commit("SETTINGS_SAVE_START"),new Promise((function(i){hn.importOtherPluginSettings(e,t).then((function(t){e.commit("SETTINGS_SAVE_END"),t.success?gn(e).then((function(){i(!0)})):i(!1)}))}))),Sn=(e,t)=>hn.getAuthRedirect(t,e.getters.settings[t]).catch((e=>{Ba.Ay.prototype.$wpms_error_modal({subtitle:(0,l.__)("It looks like we can't load oAuth redirect.","wp-mail-smtp"),detailedError:e.data})})),Mn=(e,t)=>hn.getConnectedData(t).catch((e=>{Ba.Ay.prototype.$wpms_error_modal({subtitle:(0,l.__)("It looks like we can't load oAuth connected data.","wp-mail-smtp"),detailedError:e.data})})),Pn=(e,t)=>{let i;return i="gmail"===t?hn.removeGmailAuth(e.getters.gmail_one_click_setup_enabled).then((function(){e.commit("SETTINGS_REMOVE_GMAIL_AUTH",e.getters.gmail_one_click_setup_enabled)})):"outlook"===t?hn.removeOutlookAuth(e.getters.outlook_one_click_setup_enabled).then((function(){e.commit("SETTINGS_REMOVE_OUTLOOK_AUTH",e.getters.outlook_one_click_setup_enabled)})):hn.removeAuth(t).then((function(){e.commit("SETTINGS_REMOVE_AUTH",t)})),i.catch((e=>{Ba.Ay.prototype.$wpms_error_modal({subtitle:(0,l.__)("It looks like we can't remove oAuth connection.","wp-mail-smtp"),detailedError:e.data})})),i},En=(e,t)=>new Promise((i=>{e.commit("SETTINGS_SAVE_PLUGIN_FEATURES",t),i({success:!0,features:t})})),Fn=(e,t)=>hn.subscribeToNewsletter(t),Bn=(e,t)=>hn.verifyLicense(t),Tn=(e,t)=>hn.upgradePlugin(t),In=(e,t)=>{e.commit("GMAIL_ONE_CLICK_SETUP_ENABLED_UPDATE",t)},Dn=(e,t)=>{e.commit("OUTLOOK_ONE_CLICK_SETUP_ENABLED_UPDATE",t)};var On={getSettings:gn,updateSettings:kn,importOtherPlugin:Cn,setMailer:bn,setLogs:vn,setSummaryReportEmail:xn,saveCurrentSettings:yn,getAmazonSESIdentities:wn,amazonSESRegisterIdentity:An,getAuthUrl:Sn,removeAuth:Pn,getConnectedData:Mn,savePluginFeatures:En,subscribeToNewsletter:Fn,verifyLicense:Bn,upgradePlugin:Tn,setGmailUseOneClickSetup:In,setOutlookUseOneClickSetup:Dn};const zn=e=>e.settings,Ln=e=>e.settings.mail.mailer,Rn=e=>e.settings.outlook.user_details?e.settings.outlook.user_details.email:null,Wn=e=>e.settings.outlook.one_click_setup_user_details?e.settings.outlook.one_click_setup_user_details.email:null,Nn=e=>e.settings.zoho.user_details?e.settings.zoho.user_details.email:null,Un=e=>e.settings.gmail.user_details?e.settings.gmail.user_details.email:null,Qn=e=>e.settings.gmail.one_click_setup_user_details?e.settings.gmail.one_click_setup_user_details.email:null,Zn=e=>e.plugin_features,Gn=e=>!!e.settings.logs.enabled&&e.settings.logs.enabled,Yn=e=>!e.settings.general.summary_report_email_disabled,Hn=e=>t=>{let i=!1;const s=e.amazonses_identities.data,a=t.split("@").pop();return void 0!==s&&(s.forEach((e=>{("email"===e.type&&e.value===t||"domain"===e.type&&e.value===a)&&(i=!0)})),i)},Vn=e=>"string"===typeof e.settings.license.key&&e.settings.license.key.length>0&&!e.settings.license.is_expired&&!e.settings.license.is_disabled&&!e.settings.license.is_invalid&&!e.settings.license.is_limit_reached,Kn=e=>!!Da()&&e.settings.gmail.one_click_setup_enabled,qn=e=>e.settings.outlook.one_click_setup_enabled;var Jn={getField:_e.VI,settings:zn,mailer:Ln,outlook_email:Rn,outlook_one_click_setup_email:Wn,zoho_email:Nn,gmail_email:Un,gmail_one_click_setup_email:Qn,plugin_features:Zn,amazonses_is_email_registered:Hn,email_log_enabled:Gn,summary_report_email_enabled:Yn,is_valid_license:Vn,gmail_one_click_setup_enabled:Kn,outlook_one_click_setup_enabled:qn},jn=i(182),Xn=i.n(jn);const $n=(e,t)=>{e.is_saving=!1,e.settings=Xn()(e.settings,t)},er=(e,t)=>{e.amazonses_identities=t.data},tr=(e,t)=>{e.settings.mail.mailer=t},ir=(e,t)=>{e.settings.logs.enabled=t},sr=(e,t)=>{e.settings.general.summary_report_email_disabled=t},ar=e=>{e.is_saving=!0},nr=e=>{e.is_saving=!1},rr=(e,t)=>{const i=e.settings[t];e.settings[t]={client_id:i.client_id,client_secret:i.client_secret},"zoho"===t&&(e.settings[t].domain=i.domain)},or=(e,t)=>{t?(e.settings.gmail.one_click_setup_credentials={key:"",token:""},e.settings.gmail.one_click_setup_user_details={email:""},delete e.settings.gmail.one_click_setup_status):(e.settings.gmail.access_token={},e.settings.gmail.refresh_token="",e.settings.gmail.user_details={email:""},delete e.settings.gmail.auth_code)},lr=(e,t)=>{t?(e.settings.outlook.one_click_setup_credentials={access_token:"",refresh_token:"",expires:""},e.settings.outlook.one_click_setup_user_details={email:"",name:""}):(e.settings.outlook.access_token="",e.settings.outlook.refresh_token="",e.settings.outlook.user_details={email:"",name:""})},mr=(e,t)=>{e.plugin_features=t},pr=(e,t)=>{e.settings.gmail.one_click_setup_enabled=t},_r=(e,t)=>{e.settings.outlook.one_click_setup_enabled=t};var cr={updateField:_e.cP,SETTINGS_UPDATED:$n,SETTINGS_SAVE_START:ar,SETTINGS_SAVE_END:nr,MAILER_UPDATE:tr,LOGS_UPDATE:ir,SUMMARY_REPORT_EMAIL_UPDATE:sr,AMAZONSES_IDENTITIES_UPDATED:er,SETTINGS_REMOVE_AUTH:rr,SETTINGS_REMOVE_GMAIL_AUTH:or,SETTINGS_REMOVE_OUTLOOK_AUTH:lr,SETTINGS_SAVE_PLUGIN_FEATURES:mr,GMAIL_ONE_CLICK_SETUP_ENABLED_UPDATE:pr,OUTLOOK_ONE_CLICK_SETUP_ENABLED_UPDATE:_r};const dr={settings:{mail:{mailer:"mail",from_email:"",from_name:"",return_path:!1,from_email_force:!0,from_name_force:!1},smtp:{host:"",port:"587",encryption:"tls",autotls:!0,auth:!0,user:"",pass:""},sendlayer:{api_key:""},smtpcom:{api_key:"",channel:""},sendinblue:{api_key:"",domain:""},mailersend:{api_key:"",has_pro_plan:!1},mailgun:{api_key:"",domain:"",region:"US"},mailjet:{api_key:"",secret_key:""},resend:{api_key:""},sendgrid:{api_key:"",domain:""},smtp2go:{api_key:""},sparkpost:{api_key:"",region:"US"},postmark:{server_api_token:"",message_stream:""},mandrill:{api_key:""},amazonses:{client_id:"",client_secret:"",region:"us-east-1"},elasticemail:{api_key:""},gmail:{client_id:"",client_secret:"",access_token:{},refresh_token:"",user_details:{email:""},one_click_setup_enabled:!1,one_click_setup_credentials:{key:"",token:""},one_click_setup_user_details:{email:""}},outlook:{client_id:"",client_secret:"",access_token:{},refresh_token:"",user_details:{email:""},one_click_setup_enabled:!1,one_click_setup_credentials:{access_token:"",refresh_token:"",expires:""},one_click_setup_user_details:{email:""}},zoho:{client_id:"",client_secret:"",domain:"com",access_token:{},refresh_token:"",user_details:{email:""}},logs:{enabled:!1,log_email_content:!1,save_attachments:!1,open_email_tracking:!1,click_link_tracking:!1},general:{summary_report_email_disabled:!1},alert_email:{enabled:!1,connections:{}},license:{key:"",is_expired:!1,is_disabled:!1,is_invalid:!1,is_limit_reached:!1}},amazonses_identities:{},amazonses_display_identities:window.wp_mail_smtp_vue.mailer_options.amazonses.display_identities,plugin_features:[]};var ur={namespaced:!0,state:dr,actions:On,getters:Jn,mutations:cr};const fr=()=>new Promise((e=>{let t=new FormData;t.append("action","wp_mail_smtp_vue_check_mailer_configuration"),t.append("nonce",Ba.Ay.prototype.$wpms.nonce),Na.A.post(Ba.Ay.prototype.$wpms.ajax_url,t).then((t=>{e(t.data)})).catch((function(e){if(e.response){const t=e.response;return Ba.Ay.prototype.$wpms_error_modal({subtitle:(0,l.__)("It looks like we can't perform the mailer configuration check.","wp-mail-smtp"),detailedError:(0,l.nv)((0,l.__)("%1$s, %2$s","wp-mail-smtp"),t.status,t.statusText)})}Ba.Ay.prototype.$wpms_error_toast({title:(0,l.__)("You appear to be offline.","wp-mail-smtp")})}))})),hr=e=>{let t=new FormData;t.append("action","wp_mail_smtp_vue_send_feedback"),t.append("nonce",Ba.Ay.prototype.$wpms.nonce),t.append("data",JSON.stringify(e)),Na.A.post(Ba.Ay.prototype.$wpms.ajax_url,t).catch((function(e){if(e.response){const t=e.response;return Ba.Ay.prototype.$wpms_error_modal({subtitle:(0,l.__)("It looks like we can't send the feedback.","wp-mail-smtp"),detailedError:(0,l.nv)((0,l.__)("%1$s, %2$s","wp-mail-smtp"),t.status,t.statusText)})}Ba.Ay.prototype.$wpms_error_toast({title:(0,l.__)("You appear to be offline.","wp-mail-smtp")})}))},gr=()=>{let e=new FormData;e.append("action","wp_mail_smtp_vue_wizard_steps_started"),e.append("nonce",Ba.Ay.prototype.$wpms.nonce),Na.A.post(Ba.Ay.prototype.$wpms.ajax_url,e)};var wr={checkMailerConfiguration:fr,sendFeedback:hr,started:gr};const Ar=()=>wr.checkMailerConfiguration(),br=(e,t)=>{wr.sendFeedback(t)},vr=()=>{wr.started()};var xr={checkMailerConfiguration:Ar,sendFeedback:br,started:vr};const kr=e=>e.blocked_step,yr=e=>e.current_user_email;var Cr={getField:_e.VI,blocked_step:kr,current_user_email:yr},Sr={updateField:_e.cP};const Mr={blocked_step:!1,current_user_email:window.wp_mail_smtp_vue.current_user_email};var Pr={namespaced:!0,state:Mr,actions:xr,getters:Cr,mutations:Sr};const Er=e=>{e.commit("INIT")},Fr=e=>{e.commit("BLOCK_APP")},Br=e=>{e.commit("UNBLOCK_APP")},Tr=e=>{e.commit("APP_LOADING_START")},Ir=e=>{e.commit("APP_LOADING_STOP")};var Dr={init:Er,block:Fr,unblock:Br,start_loading:Tr,stop_loading:Ir};const Or=e=>e.blocked,zr=e=>e.loading,Lr=e=>e.wpms;var Rr={blocked:Or,loading:zr,wpms:Lr};const Wr=()=>{},Nr=e=>{e.blocked=!0},Ur=e=>{e.blocked=!1},Qr=e=>{e.loading=!0},Zr=e=>{e.loading=!1};var Gr={INIT:Wr,BLOCK_APP:Nr,UNBLOCK_APP:Ur,APP_LOADING_START:Qr,APP_LOADING_STOP:Zr};const Yr={blocked:!1,loading:!1,wpms:window.wp_mail_smtp_vue?window.wp_mail_smtp_vue:{}};var Hr={namespaced:!0,state:Yr,actions:Dr,getters:Rr,mutations:Gr};const Vr=e=>{e.subscribe(((t,i)=>{if("$_app/INIT"===t.type){const t=i["$_app"].wpms.versions;let s="",a="";t.php_version_below_55?(s=(0,l.__)("Yikes! PHP Update Required","wp-mail-smtp"),a=(0,l.nv)((0,l.__)("WP Mail SMTP has detected that your site is running an outdated, insecure version of PHP (%1$s), which could be putting your site at risk for being hacked. WordPress stopped supporting your PHP version in April, 2019. Updating to the recommended version (PHP %2$s) only takes a few minutes and will make your website significantly faster and more secure.","wp-mail-smtp"),t.php_version,"7.4")):t.php_version_below_56?(s=(0,l.__)("Yikes! PHP Update Required","wp-mail-smtp"),a=(0,l.nv)((0,l.__)("WP Mail SMTP has detected that your site is running an outdated, insecure version of PHP (%1$s). Some mailers require at least PHP version 5.6. Updating to the recommended version (PHP %2$s) only takes a few minutes and will make your website significantly faster and more secure.","wp-mail-smtp"),t.php_version,"7.4")):t.wp_version_below_49&&(s=(0,l.__)("Yikes! WordPress Update Required","wp-mail-smtp"),a=(0,l.nv)((0,l.__)("WP Mail SMTP has detected that your site is running an outdated version of WordPress (%s). WP Mail SMTP requires at least WordPress version 4.9.","wp-mail-smtp"),t.wp_version)),Ba.Ay.prototype.$swal&&s.length&&(e.dispatch("$_app/block"),Ba.Ay.prototype.$swal.close(),Ba.Ay.prototype.$swal({title:s,html:`
',defaultArrowSelector:".wp-mail-smtp-tooltip-arrow, .wp-mail-smtp-tooltip__arrow",defaultInnerSelector:".wp-mail-smtp-tooltip-inner, .wp-mail-smtp-tooltip__inner"}),Ba.Ay.use(La),(0,l.fh)(window.wp_mail_smtp_vue.translations,"wp-mail-smtp");const eo={install(e){e.prototype.$wizard_steps=[],e.prototype.$wpms&&e.prototype.$wpms.other_smtp_plugins.length>0&&e.prototype.$wizard_steps.push("import_step"),e.prototype.$wizard_steps.push("choose_mailer_step"),e.prototype.$wizard_steps.push("configure_mailer_step"),e.prototype.$wizard_steps.push("plugin_features_step"),e.prototype.$wpms&&e.prototype.$wpms.is_pro&&e.prototype.$wizard_steps.push("configure_email_logs_step"),e.prototype.$wpms&&!e.prototype.$wpms.is_pro&&e.prototype.$wizard_steps.push("help_improve_step"),e.prototype.$wizard_steps.push("license_step"),e.prototype.$wizard_steps.push("check_configuration_step")}};Ba.Ay.use(eo),Ba.Ay.use(Wa),new Ba.Ay({store:Jr,mounted:()=>{Jr.dispatch("$_app/init")},render:e=>e(Fa)}).$mount($r)},3159:function(e,t,i){var s={"./loading-blue.svg":7848,"./loading-white.svg":4075,"./loading.svg":6283};function a(e){var t=n(e);return i(t)}function n(e){if(!i.o(s,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return s[e]}a.keys=function(){return Object.keys(s)},a.resolve=n,e.exports=a,a.id=3159},3180:function(e,t,i){var s={"./amazonses.svg":6489,"./brevo.svg":1466,"./elasticemail.svg":4689,"./gmail.svg":6848,"./mailersend.svg":5136,"./mailgun.svg":6211,"./mailjet.svg":5168,"./mandrill.svg":8909,"./outlook.svg":5423,"./postmark.svg":6959,"./resend.svg":8683,"./sendgrid.svg":5064,"./sendlayer.svg":8295,"./smtp.svg":9682,"./smtp2go.svg":1366,"./smtpcom.svg":9189,"./sparkpost.svg":6675,"./zoho.svg":7936};function a(e){var t=n(e);return i(t)}function n(e){if(!i.o(s,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return s[e]}a.keys=function(){return Object.keys(s)},a.resolve=n,e.exports=a,a.id=3180},3962:function(e,t,i){var s={"./all-in-one-seo-pack@2x.png":511,"./coming-soon@2x.png":9388,"./google-analytics-for-wordpress@2x.png":4915,"./insert-headers-and-footers@2x.png":302,"./instagram-feed@2x.png":8606,"./rafflepress@2x.png":7688,"./wp-call-button@2x.png":1672};function a(e){var t=n(e);return i(t)}function n(e){if(!i.o(s,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return s[e]}a.keys=function(){return Object.keys(s)},a.resolve=n,e.exports=a,a.id=3962},1584:function(e,t,i){var s={"./all-in-one-seo-pack.png":1941,"./all-in-one-seo-pack@2x.png":511,"./coming-soon.png":2220,"./coming-soon@2x.png":9388,"./google-analytics-for-wordpress.png":3889,"./google-analytics-for-wordpress@2x.png":4915,"./insert-headers-and-footers.png":7846,"./insert-headers-and-footers@2x.png":302,"./instagram-feed.png":7238,"./instagram-feed@2x.png":8606,"./rafflepress.png":2032,"./rafflepress@2x.png":7688,"./wp-call-button.png":6960,"./wp-call-button@2x.png":1672};function a(e){var t=n(e);return i(t)}function n(e){if(!i.o(s,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return s[e]}a.keys=function(){return Object.keys(s)},a.resolve=n,e.exports=a,a.id=1584},7848:function(e,t,i){"use strict";e.exports=i.p+"img/loading-blue.svg"},4075:function(e,t,i){"use strict";e.exports=i.p+"img/loading-white.svg"},6283:function(e,t,i){"use strict";e.exports=i.p+"img/loading.svg"},3464:function(e,t,i){"use strict";e.exports=i.p+"img/loading-pattie.svg"},5573:function(e,t,i){"use strict";e.exports=i.p+"img/arrow.svg"},3321:function(e,t,i){"use strict";e.exports=i.p+"img/gmail-sign-in-btn.svg"},2452:function(e,t,i){"use strict";e.exports=i.p+"img/check-circle-solid-white.svg"},5636:function(e,t,i){"use strict";e.exports=i.p+"img/check-circle-solid.svg"},8063:function(e,t,i){"use strict";e.exports=i.p+"img/check-solid.svg"},7726:function(e,t,i){"use strict";e.exports=i.p+"img/copy-solid.svg"},617:function(e,t,i){"use strict";e.exports=i.p+"img/exclamation-circle-solid.svg"},9318:function(e,t,i){"use strict";e.exports=i.p+"img/info-circle-solid.svg"},1312:function(e,t,i){"use strict";e.exports=i.p+"img/lock-solid.svg"},9004:function(e,t,i){"use strict";e.exports=i.p+"img/long-arrow-alt-left-regular.svg"},953:function(e,t,i){"use strict";e.exports=i.p+"img/long-arrow-alt-right-regular.svg"},5414:function(e,t,i){"use strict";e.exports=i.p+"img/question-circle-solid.svg"},7157:function(e,t,i){"use strict";e.exports=i.p+"img/star-solid.svg"},3217:function(e,t,i){"use strict";e.exports=i.p+"img/times-solid.svg"},5447:function(e,t,i){"use strict";e.exports=i.p+"img/logo.svg"},6489:function(e,t,i){"use strict";e.exports=i.p+"img/amazonses.svg"},1466:function(e,t,i){"use strict";e.exports=i.p+"img/brevo.svg"},4689:function(e,t,i){"use strict";e.exports=i.p+"img/elasticemail.svg"},6848:function(e,t,i){"use strict";e.exports=i.p+"img/gmail.svg"},5136:function(e,t,i){"use strict";e.exports=i.p+"img/mailersend.svg"},6211:function(e,t,i){"use strict";e.exports=i.p+"img/mailgun.svg"},5168:function(e,t,i){"use strict";e.exports=i.p+"img/mailjet.svg"},8909:function(e,t,i){"use strict";e.exports=i.p+"img/mandrill.svg"},5423:function(e,t,i){"use strict";e.exports=i.p+"img/outlook.svg"},6959:function(e,t,i){"use strict";e.exports=i.p+"img/postmark.svg"},8683:function(e,t,i){"use strict";e.exports=i.p+"img/resend.svg"},5064:function(e,t,i){"use strict";e.exports=i.p+"img/sendgrid.svg"},8295:function(e,t,i){"use strict";e.exports=i.p+"img/sendlayer.svg"},9682:function(e,t,i){"use strict";e.exports=i.p+"img/smtp.svg"},1366:function(e,t,i){"use strict";e.exports=i.p+"img/smtp2go.svg"},9189:function(e,t,i){"use strict";e.exports=i.p+"img/smtpcom.svg"},6675:function(e,t,i){"use strict";e.exports=i.p+"img/sparkpost.svg"},7936:function(e,t,i){"use strict";e.exports=i.p+"img/zoho.svg"},6458:function(e,t,i){"use strict";e.exports=i.p+"img/outlook-sign-in-btn.svg"},3453:function(e,t,i){"use strict";e.exports=i.p+"img/pro-badge.svg"},6915:function(e,t,i){"use strict";e.exports=i.p+"img/working.svg"},1941:function(e){"use strict";e.exports="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAABKdJREFUWIWtl11sFFUUx39ndqf0C0EhiKVluy01ARuoxMRo1CBBIqKRqNV2C4Sg8cGowQcViUFtFOmDCSYaE9SEqN0tluiDIRBBosYHQlBDowbSwu62fNTKh/JRSnd3jg9TdruzMzsN8H+79/zP+f/vzZ17zwgTRfNAGSWZh1FZCtoI3A6YwBRgECGBcghhD6R+oLPh/ETKii9j9dHZpAPrgVVA5QTtXgS2kTG2sH320Wsz0PxnCWZ5O8grQMkEhZ24gmgHZ9Ob2NVwZeIGVg7Mwcp8Ddx5jcJO9GClH6VrzoC/gdbkHRi6F2XmDRK/ipOotYxYXc/4SSOPsioRRvRHT3HlBOiHwBGXaA8q7wP9HgaqEGMXLX017gbWxEvJsAOY7lGgn3SggWh4HYb1ODAyLnaJACuIhTZQWTIXYdDbRPA7lvVOKjSQMt4CFnok2tzumssAfFV3BGUxIq+jvAbWYr6sjQOwtWoYJehZRVjAzcE3ckOASLIO9C9gklceoJRoOdvCI0U40NZ7E2r+V5QDV0DmEQ0ds3dAdb2POKhs9hUH6Gw4j8hmH9YkRNcBCKsGK8iMnAImOxR7QXqBeajEiIU2+IqPR1viXZSngB6ERpS5DsYFSkdmCa3JpxHd7ghmwKonWpd0L368mlEdprvmLGAf4FGrhmh9ryu/JV6LIX1AwLHIFQaG3ueS8runOICmOzDTL2fHo8ZjENjhye8KJ4CegnmRpQYqd7ukNNGWWOtZEEwQM1dITQTTnapCJPEisKAwxIIgaJVLVhDlc1qT1cRC7dnZRRqkKnk/yK2IpokklwBg0YhoBZHkElJl++mecTGbE0m2A296LCQUBKZ5rlM0/y2ojtdjGftAQQG01eZll7QHc/hJ4JtxWY2e9WGaQcHBuE6o431R26oHUgbg1Tgowt58ejDtayBgpPLGhuwCLA/2ZQPkmFsA1UforP04b3bKUD+QcuHnoNqXN+4MfYrqYuwmxQE5YqB6qLAIR4mFdxfMb70rBXQXkf+VhtmHC2Zj4Z9QCjsj0T8MRPcVBmgkEm9ylbCMV4FCERgCfY63Jbfda+KlAETiTQjzCzJUvxfWHp7MSOkgUO4InwZOAnMR/ZaKMyvHdgCaB27BtF4C3YD9DXxEMLOFL+rtXuD5gyYXpkcRngD6gBnAVEf9i6QCM8Zew8RnwLOuK86hi2goApI71W2JUygW0dpZecxIIga0+NT7hGjtC2P9QKYDv8MFLbT1Tfbh2O07POPDGkGCm+BqQxKt70XY4pN0Mq/Xbx4oQ5kCTB0TtWE3LfGilYQP6Kw+njMAYOpGYH+RtFJa+u1ru3mokmCmEygDyjGtGGsP27tjc4rt1EEqTr+T8zIeKxO3YXEAqPZIHgZ2Y7frYUesH/vFewiv5kY5gcgDREPZu8elLT82HzF2FjFxrfgb1UXEwnmfsFFAi9X1kEotBPn5Bor/RoB7nOLuBgC6G/7h3OhSRNuBS9chfBnhPc6l7s12zQ74/5w2x2diykZgNVAxQeF/EaIEMh3Zy8kD/gayRoYqKbm0HIwHQZtQwti3WxrkDOhx0AOI8Qujxs7sP4QP/gdLfYuNd8XCxgAAAABJRU5ErkJggg=="},511:function(e){"use strict";e.exports="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAACXBIWXMAAB2HAAAdhwGP5fFlAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAACT5JREFUeJzNm39wVNUVxz/n7W6I/FDkpwpmd/mRwUIdrfijKNZBOq11xmJhC7tRpKCpta3tWNGx1hoc2yIFrDJOK79FskHiFOSPSmvr4LT4C1qhVgVi2N3EURAoShJIstl3+scmwLK/3r73Qv3+tXvvOd977tn77t57znlCb2NW00VI6ipErgTGAqOA4cBAoH+3VDtwGDiIEkP4ANhFUl+nPnigN82TXmGdFbsaQ2YA3wK+5JBtL8IWUmxmg/8NEHXBwpNwzwFz9wygvc+diNyFcolrvJnYh7KSPrqCtcHP3CB07oBQ43n4PA8APwTOc8xnDccQlqGyhKj/qBMi+w6oUYO9ibsRFgBDnBjhAIcRfYTOwArqJWWHwJ4DwrFxiKwErrWl7z62Y3jmsP7iD0tVNEoeKpy4DZGdfHEmD3AtZmoXkXhVqYrWV0BIPfjiS0HuLXWQs4wnSfrnW30krDlgTqycTqkFvuPEsrOIepJtt1E/vrOYYHEH3NTQh0G+zSjfdMW0s4eXSbZNK+aEwntASD2c79vgwuTbbOgcdjjmTfj6rSeknkJChR3gS/wWmGbTgBPAKtDLiQb6ozITMC3odQJTiAaGojIBYRn2HAgQwpdYVEgg/yMQScwGfc7euNKMeCZRO/KjjOaq+NMoPy6iW0PUvyCjaXZjBV2eHcAwe+ZQRW0gmqsr9wq4rXkM6DO2BgNAX8qaPIBR/hCwv4DeuyRbf5PVvG50E/CKfXN4lplNo3N1ZTugRg3M1DpO3dTsDDgiZ/vzF7ShejPwKrAfZTfwb2A/wlZMbsm7aeXjtIb+GKk11GjWfL1Zog3xapCvOhgMhCvy9tUF9wA3lkaogiQud2aTTKahaR6wIqM5Q2hObCCd0ggMcjQYQNIzmPqL/+uYB2BWLIAhMReYDlGmlaffJDOXRFLux43Jg0lZe5cLPGmkaAfciAMMpVPuO73hlAPmxAaiuHPMFX2c2rHHXOECqA8eQPi1S2w/oqrh3J4vpxzQIXOBAY7pRR+jNvioY54zURv4BeiC4oJFcT545/Z86XaACsI9jqlVftcrk+9BNFgDLHXMo3JXz8f0JpiO4b1pUf1zROZjmocQLkNkIspwYAuV/l9RI1ZOew6gQiTxM5SbMfgIlZ2QegeRC1H5PXC+JRpTr2FD8K3036Ah37VugDxKrb/nr2Rzaca7AVGiLAYWZ3VFEsNBn7JEY3Ar8FbPHmD1stNC+YnVFmUzUb3TRzj+MOH49LwyMxsrqYovyndqK4oycx1w3JKsyC0ABrObR2A5dK2bWD2uxZZxbUO/gfA4Qh3VO305ZTzex1Dm4zHt7SNrg5+BvmhJVhnH7R8OM+hKXW15ACFuyzAAk77dn3ycGFmWR6hHpp/tcUQOWpUk5b3OAC6zTG7KPCKNY20ZdjZQ1XQlyjzrCnqpQSmZG2EEeN4hHL8HtHeySnZwg3oJJ36Jmtsp6SRrjPOCVpQYHe+H8AzhxFS6NGQ3Hu8aqnf6aE1sBabY0A56QexdM4VbKYvdCPwlr0xVw7nguwsVL+ilJ9tT7fcRSWRfe0XHoIBSSSTxIACGvsL6wL/yjtE2ZCr2Jg/oMC9O7v0YRTJCZdejujjHPeaxnHebniZhAujC7rYJwO15hzB1IGL7aRxsAOfY1UaM1sL9Unri5UxoseeziA2F4TNwcs1Us2DE9azA0OygjnV4DMDewSYN+6vHLZha7kD7uAHYX0JqlpyMdB3pahKbFzA5ZmAvAZFC9SGio94uKKVd7bbsykRhjmhwF8gPisrlhHnAQNhXotY+RK+jLriwOD/O63vEAkfUv5wUXwEp/INkwdhvoLLXsryym2TfK6gNWosdfBJ8H3AWGlNetyT3QuADkq2Tge0lkO8zUP2PZXlhC/XDrO8Z26QL2GjdoCwcpExftSxdP74TxHoCxTB2Gni7/o71v8JJlslPIrUIW88ngD7B2mCputZt7Ei9bfD8mE/B8iqYUvJtMDq6AZUHStJJ4zWSgadL0pgVC4BaTLrou9QHD3Sf1OSvFocQ8GSHzkPNhc8Ddf5lIDVYX2nbSaa+nfeiVaMGodgFWYEVj8wHrB3OlJfhZFC0aSKGucOicSYqz2PwCehlKFcCg4HX8Hqns27kkbyas+I3Y+iTIPlWUSuiS+l35HGWT0zmlAh/PASj8yWUSUAHyG4wd4EMo5RUvhhXUVux49Q5OxJ/D6dVncLrdHqmUn/xibwyN6iXC+NTMWQNygXdrZ8CPyfp2VQwnVb9cV9aO/8GXOPITnifaGA8ZKbG1jgkBWUSvtTLhBrzF0xuky7qglvRjP/3ZqKBVQUnH2o8j5aOrTifPKArez6dckB5+7OAo6rLbnwNn+ePuVLR9qGCz/MiIpNdIDtKeUcOB6we1wJa2q6bH1NoTPhd4oJwbBgw1RUu0WWnR7bP+JWMp4BDrgzUnnRyT8/EgPIWwI1s80H6dGQkVDIdEPUfRfVBFwb6iPqxxRx5WiJWz80vBiy/6DjKHsdWiTxyZl4j+zmtC6ylpPN0Lug7BbvTmZ9Rp1k2Jl2XVABCYc6iJrGN2oqVZzbn2KhESRl3AJ/bH0w68vaFmgfhSdWRGYoWzNRGQg1DC5A6KZBowTTuzPWyRaEyuRCo3YtMEvgelf66jGxxeP+liLGJjF8/w5xmSM3IiDOE1IOvKQK6AuhjyxqVmdT5c86lcMAxEl8C3FdQpjD2ASsQeQP0JpSfUjzt1QH6B1S2YOjVqNwNVNi2QFlCXeD+fN1FIq4qRJpWg86xbcD/FfIClRWRQjULRQ4rovQ/VA38yWXLeh+qW0i2zi5WsFH8tLZ8YpL+h6cBtW7Z1usQ3ciAIzPcKZc/CRUiiUVA3ufpCwGRhYyteNhqqU7pOaVwfDrCKs7eG2JWcQz0+0SDG0pRspdUiyRGoeZaly4nbuAfIHcQ9RcoxM4NBzl+Faris1FZhN0yduc4BDxE1L/a7hulzosc5sQG0mHci+hPcKfM1go+R2Up55x40nbNUjfcq/IIfdof7/FqhLnAeNd4M7EHeIby9uecTrwHvfTydPxyDCIoX0f4MnbeT0xD0xFr+TPIBqL+f7ppJvSWA05H+OMhSOf1pOONlwCVpB+VntfnvaQvXieAJqAZ5D0wd6H6JnWjrFZ92cL/AEdm6o5wcBoEAAAAAElFTkSuQmCC"},2220:function(e){"use strict";e.exports="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAA+OAAAOwwHS3rpiAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAABpdJREFUWIW1l2tsHNUVx//n3nN3dh0nTRxLAeQUg3GVlCREclFUtbgOMpFSEQXUYEirRlDaD0nqBFNQm35otv1StbT0QSXUiLZQpEBqESVA+kKAo6A0gB3aSo6gpPb6oZKWJHaM451753H7YWd2Z8Z2DJV6pKvZmTlz7m/+55x7Z2l4a+N7XuDMeKEz5IX5IT9whgKbf8/4zr+0z0OvvfbZUhHFEP8no7E7l7zlhbn1fuDAC/PwQwde4FSOYR5e4Lh+6Ix6oTPih/lREzgjgc2NVI7OyMjS/Hixr+j/zwDntuUOe4Fzpxfk4YVOAmCe88CBF8FFv10/dAa9wPmbbwsvh274+55Sz+SHBWAJU7KCYEFJrmhUzNrKuQUAi8qxdj8PoM2C2hDQVzzH8X7U+vifPJv/8b6z9/UtCECMEgc6mgkRSDQZZk2WArSZZyJnBdDtCOn277f85pTn53d9Z2T7W/MByIfXYwURtgsbAARQZbIzBDwBYIyIpgAwgHpEHjEPAQBRDY8ysBZNRHT/5z7WVdc4eXffGfRaZIylQMlGzyjfAJZgYS+2PP+fbycd3918g3PRXHWtFdRMAZph0QxQiwWth0WrrZLNUost8K21zWLdddNH7/nh+a0fpO5e6MYSTOMSfMD6QOgT/MAZvuawe/18smXt6IavrvB8cbdBfrcXOJ+IC9WvdFHUUQ78MH8iRHlTsXSfGz8rlj+GKZK4AAZIAkJasDQrbQf4wwJsff2Jf28bOPDzqxc33MjS3cVSX1bCgIWGkhosNLhyfguFhSdTCgDAxE70Wx9t1quoAB8IPLSseA5DAGDvgnyn3LzDhM5FOcMv39g3OH0loINtX1/l+3XHTOhcX2njfEIFB55f2LF/tOtpABAAQAolkgBxZYABKVFNAfUiKNjwiCK9Oyz4509vWvfSG503f61/S1vdXABfHPjF2yrndyihSyxMQoVoSPcnxabfNVQBIFGKJ4+HdZCqgWuPjU6cu1z6PEv9S5a6k4U+EJTl2Mlb2x/qb2tTWYjtbz46Jth8gYV244lVlAol9XKl3J01BRjDWQCSmFWEG/vgr36xtFcJvZ+FgRK6QQr3EbOk7q/H2ztXZ/2/PPDT0zlhvlurBZNUorvY8SpXFBAoIZI+BpCMlvlyvPpY6XtK6sfiYFLqT0ppTr7a0dmR9WUz/qgU+p8sDFjGKmgoaVbUjQ9/RgCAyNVSEENgDgWSturm4QekcA+qWoUvVWQOH2/fdF3Sr2uw1yhpHqmloKaEFDObBQDUSwwTI8xArBnrQWE+ACoiLDctv5eF+Xui3ZZJ6T5jM6uRUO//loWeqhSgqakg9HoRBZsRjKFkDYCRq/ew4UoqfOrAgKeE2Vt9M2nAwmw4eWv7bSkV/tJbVmSOpFXQYGFaRexkJfoTBQhiQDDuuBIAALS+ON7Hwh1MBpfC7M36SVl+oVqE1VowjVUAYryETCdA4v7JnVi2EAQL71mVCM6kbzu1ecOSFEAh7FNC22Q7stCyChAuwgvEMJApiHrUYd+CAOQez/S6kp7emPTZ0vfMeZZ6rFqEFRW8KsDiPXifGEfjIozVEIwHp3pwy5UAKPdBP0sdqkRwlt7GrB+TOVvdIyrA4yLpYBV+QAyb6QYJhUOXHkbrfAAre1FmoUc5EVwJfVPWT0r3LKeX5ZEUwKK9GCCFQ5luADGuJsIrU9/AqvkglDAjyYWGpV43h8+7qU6Q3usi6xQo9BDjfLIjopQ0QeKNyR50zQVAbCeSG44SpuGdLdc0pgDIXKwWqjDIyZnjswDqd+McSXyJGEF2fwBjsVA4NNWD3gu7sDINgMnKt4RGnGcBfDzpw6xNdUMS7oXLl+ypWQAAkN+DP4OxgyT8OSAAxjZ28PZEN35WBWFMgaMPmkgFh2aaknFzVPZqa4F5tmuw18wJAACFbhy0CvcQw8wDUScYe6TE0MROPE+MtfE9wSGU0BDsNSRjSqG9uAZywvwaiL8H5rG6bjwHRicll2k5q0CZGFtIYmPyuuAQOVFenIynhM/RnvGHT79y4vSCAABQ2IMTeQc3kcLjyQ0rBZFevBIqhSkAKcuNLLTNCXd/fG1BAACg3Zgu9GCXFFgLxlPE8OZISfaDBkIiBZATppGlfnrNH//x5kcCiM15CGcWfRP3Uh4tUNgHximSs7bx5MinFBBuUJDTD6Ze7qMAzGXTRVxlA7SHHtbBxxrrYxV81FsP9aGPJ5f/Cg/EvhN3YOmyI0j9cf0viS/aZy8IpPkAAAAASUVORK5CYII="},9388:function(e){"use strict";e.exports="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAACXBIWXMAAB8dAAAdhwGkh9VpAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAADg1JREFUeJzdm3mQVdWdx7+/37mvN5pFERdkaRqj7bCESUMZkxAagjGMoKJCJW2cCs5ACpW1UWqmUvomTvgjxoWJJjGVqINLFEUyg2B0TEDWoHaCtguCvu7GBiQgTUM3Tb93lvxx33LXd18vaNX8qrrueXf53XM+9/s753fOvU2N1533qTKiQ2srYYxIKFgJra3DWotDUFZi3DcamigOjf+nRs3XD3pHG2ucMgJaW9DGgjIC2ljpP5FUWrRoYx3WsA4pbSW0EQlpYgklkRjU2frJxPr61BfdkJ4afTK7/0vaiGuUsdIARBqCs5yDo41IH0sf1xaUEa3aWAljYgllKKFM0WGtxCFNnOiA3P/93U+f/KIbGmYWk2y2iwQwYIudYLxnEmWLrmMMGI1zAKrWQDXDgkEKEAbQFspMDC9M+tej2ljNGtYBpUWz1lazhtUEQwc0lTTO2xM/cTYbmc8sZnUA2m6cAVwNzRnBZOHk9uWK7mtM5ngO6BAAQ2Aw0ZDJ7tcQMDqJ3467+2/aiL3axN5JafEGjLX7jr11+/qmifnNIqhmdtbf0dBsQzJGuYJx7rRVgIATAQpQkwsOoIDzyf77pmADrYGfX/azTzRir2jDG9uS5X+IN80707Mm5jc6chO+BogdrtjXuU4w1yGmYz+kn9Da3TcE9BN+nzrAj6vPyfpp08Z6URnx65Ufzf9znwI4NgcXG6BFhzTUV7kQOPYx57kOCB44bgh+YOEPwYI2ol4b62dnPm5eG0e818MzDx6Dw2B0MSkwSdjbXFl493HmmITwXJM713+N+1z/fXz3ZO9xmSlXE+TviitHNqyqXHNDrxUAAMe+hw+NxqXQCHwKbhWI9JMOkLpHIcEqCAoFv9rcKghSiF02JvZa0vCieFPt3p4AEABw15cxk4BLbCIauU6MAFD6FwFAO0AWKNPtU/YosmeR73q76PTjvsZddtyTAvz47mkqGfQvUwfNPT3lxLg3tmCLv8/NYxYAgNGYdQeAtbSPMrlHBDKLLyk6vGZf57ALGVyRghzFZCoMMBIwFQAqwDTCaBT5G2j/NN59nvs4rzHZn35Q7mGZSg3wAFdUXR2Xa2vjLXOPdwsAE5oM2zfMQVB2BRw3IkND6XkooOUggIMAdngdmjh419YrL7KEHqVkqsIQKhgYSYYqwKoCGiOADCAHkHRDfY/P9RD8QD2Qr4ZlvRkfsXZW/MDc9wsGYCw0QuUab28NhFauG2lgaJRDe+K0KwNou/d4HHGuvvKtiyxROspINVaQqYZBNZjGQiPmbWFOBX4zLuVk85ZKMLb+eNgL19zdctPuyPoCwLH5mEQSb0AD0OmkJr01mnKdGKzfD3+xfXaU057Y2ivnlFpqwEyl+WZlimZoI4qC5iKeIdEz9Lo61nZNsaviTTfmzRsIAE4uwHlS4Wim4VkIKg3BkF0BiPqh685MPBsAnPb0uIXncBEWGB27S0Oc24uJWmtK8ZR7W+Y25AUAAMfn4yQ0+rsgqBwMYwhGW60XrEude7YBZGz9hKWDOknfpWEtUUaU+VUQkYDZCmkyKT0pfqj2WNA9sgBaF+BtYzDe+/ThCgdGZ5E+d+QzaP2cGAAAnqm+o0rp2HPaxMbncpPg1NmfolvQxvqTbv7gqqDMkbMlgSZie493mykTa5SlUBlW0be/fUG//TOGjzZxh98+sNr6h/cWl+CrTPLRoOxRkAJzUEZq7yeS02hkVV2Q75wCbsNDMFgSpACnErTB3POfw/Nhld03c+g8ZWL3GWN9qI3Ypo3YmoyVbZm4of50X8B4csKyO7WJ/bRbEzU7FLoUiifEm25yZYzsKDVmnzYhVAkMjM5XwUtfOvS4MHI6kTyfSK0k0htjqc6jf7lq/Lq3pk+o/fOMKwb0BsAtex68T7Ba4Z1XhKsgu69YmK6fe/05Q6DRK/mQbWgIZCFsOrinqEtMZKhX0xUoY5Y3MOunLZk6+Mb0SY9sn/r1y3oK4ft/vf9+QfJHvomar+wAwhLMavpPRv7umkAAsbQCMk8fITCMiAYAAKNfS7R1HBk8k0k9wSQhcrO7ciZ1W0wkP9j1rStf3jV18td7AuHmPQ+sEiT/xz+LlO6+wQMEnLonEEBnLLoTLFQBGZtYX5+q2th0qyB5r7cighQxqe+A5fYd0yav31xTU9EdAASYFPQPBMmPC5liOx7CpJ9UPvUtH4AhP8UpCByNhEAYbhZ4U9b8Fa3a2Hy3YLmUWZmQil5fTOrdbVOnLjahia/f5u156IQgdQuTNK7Yd6wleNcsmCQYydt9ANLWlC/+wQAJWG1dGFFoJTNW9VLTaoasC66cBLHqR5Crt9VMXb+5pmZQoX5r//rQLovUmkL6AYcKZq265LEhPgAkbABh8Z/Zp2KFh4HT/mFT04MMvTyictcJ8M7NNTOGFey4yKxkkif8KnCMEO57WpZRs30AQEhExL+91fmHwvwQEg8yq3uDK5dVxOXCnHn9j9OmXVyIz9rdq48IqPsdy2Z51SBYgUhe7wOQUUAkBIFRPQUAAJdvbLyHST0ZrgIJZlUZ09iwuaamvBCfWspHmFS7OzvMs7ZJevKj1Y/G3AACFBAC4ZLeACDAxIyYzyS3hUg0U/5Hy/Cjhfi8ueGXrYL040ELsoELr6zK29tUtQuAQi4bDIVg5wnjewMAAL708kddVJycLUi1BEk0UyaWtVumTCtoDcJi/RCTMnlHAGfHK9QEF4AB45EA40y++E+XR3+2CL1KaQHg8vUHPyMk5wdLNLe1WK3eNGNGcZS/G9/8ZYJJ7fSpiYOBWCzHu0NgLhQx3g+Vfi5LJNL4Rm8BAEDVppY/MMlNfom6gAwv7zp9ayH+GPJZ3xwhrGM0cpQ3DwAEGgoZCZgxsy8AAAAb/eOQCUxOBVArCplma1IvCJLKpyYOAMJquM8hA28XNBIwrjVz7PcKvbVLN7XsZpIfBE5gcjFbuev1yVOjfM1984lPmdRu3xwhOE0e7AOgGX8MbLB/inzxqaGY0RcAAIBIPhU2gckBSc0rxJeA2hyoJnYCkWBS5T4A/f4dDcQ4lK8TzPwZxsK+AsBIPsWkdMgExu61Sc18b86YokhfrLb44AWHV5EPABEMCP8XMPQFwfintiW4oi8AjN7QeoBJvRc4fOU6xIGnTpTXRPkyqVM7mWQyUE3sAiKDOxUL6yLT4czWwqq+AAAAguSOwOzQUbYgr47yM6t+w2lm+Z5PTf5+oCsQQFkHXibCYe8CSRAEw5jWVoeb+wIAk9oROnxlVZCaUpAv6HeZQ5KhnAqOBQKgOCQsrCloYmRvH+xYiot6C0CL5M7g7wJcQCa8Nb16YCQAkWoIV1MWaDAAAGDCb8BQ+TpBx7EhqSI8a+Lpt809tBHrzjQyqdOhw5cNR8REZ2QqbmnzbuaaPMnQgVAAJcvxERjPRC6QZBIj4Jsn2/FfvQFAgGGS+0MnMJnRACYSAMe6GsNS6ywQofbnzazY4D/BUIVCIMbCtjrc3RsIgtT+4OErpwISyXHRnpItzmuCkiFh9Pt5AZTUYR8RnogaCUCOfQL/0bYC8Z4CIKQXOdn75HJhIYyOVMDULVvaRXaVKFhNJNS2yNw6VYSVxDhayFKZY989J1fgV2YRImdwPgAWjnhj1jd8CTW2kMVTJnXQOSMUbp8f37j7Ny2RAAbcgc/AqCtkRPCUf3iyGNta6zCyWwAIR8HGmwB5s7r++2YOi/xYgyGPh6bWUFsB75pgiJUuwZMk8Ps8CyRho8QkJtS3LcN3ugOAGCAycIaCryEwkSvTgtUp74ww60ckXy8YAAAUF+MHYOzvRm6QKQ+GwKa2ZVjTfhsujCaAtowPG0LwQokgNTzKFUO1h6wMaan5tW4BoB+ijWO4CYyOgAWSKAgExi2qGHvblmBxvnyBBE47fRCZdCh4GiJkJACwbPd1gixhkd45a9fzB7sFAACKb8M7RLgBjK4eKAFgDARjdVsrGloX4Z+D3jDJGE7DAzYbDo6GEKIBCFLJoNSaSD6bZdQdAABQshivGkItGLLALDFoXxUx/rutGPuO346FnyxDacZ/EbnzjiwE1t6GRL4zYJIUED6dlu54pscAAKBsMV40jO/CsYCat8HhoVLBjF+UJ3GodSEePrEAXwHCfdkQsvnA4EgArMi7MiSg107evj37iU+PAABA2SKsA+EqMI4XmCXmU8kgMG43AvWG8Uo+X8Qawl4ciXx/yKSJ2Tv8JV0fSfQYAACULsF2Ar4WtJAamCVGAbKV8qWoMCLWYKhzouonKBXzjACvfHXz7vo+AwAAJUvxYYnCFWD8qsD479WxTJk5GgCz7u+c/zOlfIs3vQYAALQcnaVLsZCBa8Fo/jwggDEgKh1myIHZjhPy5a+82rD1rADIWMlybChVGAPGfWAkI7LEXoUKMahlDkry1YfIBsAkNcfMvwWd06cAAIDuREfZctxFApcZxuPEkN2Vd6HH+sfyAxCkBtrxrx8b+9K+t4PO6XMAGStdhqZ+d+JWtjCG7f6hPbRRVKBK2D33SOlc/hBkguSFTOqoTOmVYeecNQAZK6nDvtKVWNhFGEaEZUTuN089jH+AAasEoe8I/jZnSDmTGkCkVox5pSX0HygK/iCpL+3kKlSRwndJY5bRmAAF9n6m7/1C1QR8wC0kKgc9af+3i9daZhdfCsTuG7a+/bp8dflCADjtVBznk8J0ozEFwCSjMBYasUAIyr2PDUYPegyJIL+fzi4aSyp29IL/7TiS7/5fOACvmThKTp7BONj/xXYZNCqNxnmk0c8olBuNAdAYYDTKWWFMGIBC7e8sGqmBIvaRSgAAAABJRU5ErkJggg=="},3889:function(e){"use strict";e.exports="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAIKADAAQAAAABAAAAIAAAAACPTkDJAAAJO0lEQVRYCY1Xa3AT1xX+VruSVm/Jkh8E22Cbh20CY9K0QHhYQGDAkCm0hB/pDIHpJM1k0tTpn7QznUD/tdMfmB9N25RJITOdTDrJ0AAFCrQYUhJIeJinAWOMjbGNLFmyLK2k3dVuz11ZtgUKkzOj3at7zr3nu+ece85Z4DtS6/qTm1qDp7xPE//5hhOtT+MX43HFJh+fa113aqbFiZ6MpHRwmnlz27GV96fKMGC6Qz1gNpuCqqqtbDu8pn0q/2lj09OYeZ7GK7vKK51YuLyiiRe1K60tx5vyPGPsVK9U1nqCbr8IXcfOPO+7vIsCKFBAp7OY+VetogCzxYT5i0rdDo/1DJNhluF4U3tVnbfa5jBD13SINiFYsH4K2GKAhGKTGtD2i5YTUU4SdsCWDbp8NkNMy+oGiNkLfK5r58MHVVmJVNb6PFZbbhsyP6x2AVJKDZJb7ut2ZbcOMGstLKaHzRUFwIFrql/o99y9EV2lKvoldnpGiqLDynMGiNoGb1V4KFVFJzZ46ZRqvE3EN+n6q3Cq7/jLHdVj0Ywx/22PogDAwcObeTQtLXPHhuUgU8woI9EJxZzXeCELrz9nGYOXzgHQsho8AVuTL2BHJq1AoH2eRgW3gPmOzN/Mcdyu2QtKvR4fD3YijXyryjpSkoq7t0JQUyaQDM1n4fRaUDbNAykpw2LlCaAAkym3JjyUwGgkQ4GptxLs021H1nY8DqYAwLsvn9Jr6r2wOwXaHCDzw+aYjNMvT3VBlnRSYIJF5IlHUU9xESh3w+GyQpE1pCUFLq8VUkIm8ASUNEpJBaPhFIpd0QIXON0WWmw2QGp0YqttEl9oYJQsoKCmrgI+v+vxgxj/mcmZJUS7mQ5hmZBhQZqMy1BjpicsUAAgPCShttFDwlnIGc0wv6ckJ5IYk1HfWEUbi6hudMM7XYRM/h68Q2buTxvKnG4rucBsBCmbYFZgYJhLGLW1r4wZgymPAgDkq9PEa2bmZ8SuHfuxOCirKEHDsgAWrayARZh0S3yFggfhJHouxNB7LjahnK1n11Jne5F4itxQjAoA5AXs5HcpCToNXSlSzmj51io0zPPlRSbebqsZdeUu6IuBQK0dVz4bgkrWY+T2ihNylCF7J/5MGTwBQCHfmy0cxcLk9ZmzyF9UeX4fUeDht1uBMmDGYi+6T4/gQaQT94Yvg/MkyQ12xOzx6YubN/wty+l7vmk/MhELjwHg2jVNa05LHEU5nX7cd/O+X5rXVfDWhiOQL15HNjQCW1MDUE4BOkfA/z78GLOfr8J7v2mF6HAhS8cnEoYHh7bv/dPe7bxm2nXuzOHfssnJY9KfRbO3BSuqHUHoHHiB8iHd9Yo6J+YUMb3a04942z4DgNr7EPqZrwFZxh+PHkXz+mXY9soWZGh7FqgaAfDZLJhXVYHmVc3o6R8M6pqlt7+vq+MxC1C6zehweiZxmWyTAccQG0RRKtRUQtz5FpYuXw6O8sJMXcDL4Ueo3vgiXlq3Co8SaUNxfglP1kx+fBDZQyfxq9d/gp923tqzOLiuvWB32qddzuRSan6hTJGs5K/F+KQupYxRlp5MeTabxZV4BJ9JMbS0rEVYyhQon9jrbi/0ZArDV65i0+aNbi7LbyqwAKXcWXnh/Ds1oqB/VEKNz5mfQmLfp+guceL3hz5laRaSJBk8c80MuH2UR+TCQzAmC9TuVd9D7dplaFy0EFrfAPb++cPghAVYHXA4rXsyEjvXJI30ShilJHQ3MoZ4JneX+cppqDrxNR503sbY2Bil7dy1szichvK/R77Bhtvv46tEz8RGWVVBim60h5Qz8nq90MF5DQuwlsru4v5RXuWyx6M58zKhsSilT0XD5ztvYP5L0zBnaYBNA0t+AN/Zi/iocgH2hnowpGSwtaQS+/v6DbaSzmXGzr6bqHNyqLHEEb5zDnWrXzP47PHw4SA99fsGAM2uttY0ls3OpMZT4LiY02dBlgqMr0zEzSOP4ApYMW1urg7E3twO56HjeLujFCYpjcycOjwzNoLb125gmWrFc/U/xALbdCpCIVQd/SUELYOeB4vRLzyPAOWM//7nDOnX241w//Hat/7tL7fyaar3kVAK5dPtBoTUmAIzFZKKGQ5YLDzunItg9vJxK5jNkJ+th/TiCiTXr0LomXokejy4ePM4mltaMN3uN/YQ7Q7oZit03oKRuS1I6Ty6egew/y97B86cPLCNY+32s4sDB2xUgkdHVPR1RVnfN24D4F5nDO4SKzz0S4zKcAdEuCtt8FSKMFtNiFEhCndLSAzLxpru0CVwlWHsePP1iT2mDiKhMP7a9j5mmJplqd8zV9A4LciUM6Ib9QRVz3Kj61oUcWosXD4rkhQXzGzxHgnx2JPRXlf2HLr7L+G9t9/Fuh9tRNXMGfSrxp0bt9Bx4QJuXOjEioZN8LumWa5GQh8I/jLbmqlabQ4LtVJZKkS5ZBQLp1HX6KPynEVWpR5hfJ4354rU1LX5MQNRWdKIW8dv4tjAWWjmJJyiC9d7vsR83xbcvSjDtwIwi8ILgkkwTWMLmf+ZgmIUj6bhof6PJ0Pl60MxualzVkEEA2Idm4XKOjdlLA59/feoyZ6OZEJC6GGSlfqEYHeYjRrLzM9yP+uKuq5GWTMpWaymXDTSzunxG2KmYGTVktFI6MmO97G6/yiTUZJSQql92BvGXHEruuLHMce7BiPUQ2TS2gGhuzMc0TW/n/mXtVzMBi6q40MPxv5AJy73BmxvsA+OBHVJeZLJRamEsp+s0UHfAbtZf5gn0U6NLOX9aCTz1e7PV7/A5t/ZeOJfLp/YkpDisAul1KRwCA9GUw7d/2tTSk5eu3a554ur5wdx+/oARf3wJ333wtRgZiI+v/0Nf5kDgQonXU0XWKvNyGhSOO4+dZwd+YaFNaVMhsmW0Bp/mX0J+3Ji8rsPr9mQiKg73Db/kUHlXPpu4gTi8vBrrEUT9LS6gxPFmJQaO6br6u8++OKVf25f8cl9yNqh6Ii4Iqtnt/gCDoQGYxDFyUaTbTyVFErTAw+S8Je66HakkIiqt5HmJnpAasn3kfy+hqYlrY+yHcFB+fJZtv7bQ5lxiX62+uB5XdNKeYF3q5oas1kdRr6lkNlH7A7KnW1MLi2nKnjOFKDiRI07whk1u2pf++YJAEymGP0f66rSztLaxrAAAAAASUVORK5CYII="},4915:function(e){"use strict";e.exports="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAQKADAAQAAAABAAAAQAAAAABlmWCKAAAY/klEQVR4Aa1bC5BU5ZX+br9fM93zfr8YHEACM4go+ERFRSA+EpMyagLJ7lZWrQiaVG0quimSzSZViVmJtWUqtakKxiQmu9GgRiKggkIQFRA0KA+RmWFk3tPTPdPvx93v3O47093TPQw6Z+r2vfd/nPuf85/Xf/5/gFmGDSt322YL5aaVuz2zhasQHlOhik9b7nbEH9m4ZtdtStJ065aXr+v8NHjuX7nbZXbGf59U40Xsf/2nwTHTPspMG86k3UNrX5mThHpaa6vCByj3/mL7qr/OpK/eZuPqVxarBvU5RUGrlKmK+oUn/nrTX/T62b4bZhNhUlV/KviaLnLDYjO6VagvUBoenek3Nq7deatqTL5pNCqtJRUOkAlQkvivzSt3z7qk6mOaNQZsWrOzAwq+aHeaUeSxYvHyCpRV2hSW/ceDa3c+o3+w0J3Ef5/kPm+xmBz1c9woLrHCRTzkQrPXmVhfqN9nLZ81BiSBB2QwZVUOJFXAYFQwd1EJmto85IFy18Y1O/eJbk8dsKqQQVtJ6Q+sNhMa5npgtZsQjyVg4OhECqCqG6f2m52SWWHAd27a4VQU5R6zxQiRADVBDqShqt6ORqoEKbnS5Ii/8dDNL5fqdXJ/cO2uZ8mg9cUlNrbzgOKvVSfJRZVonMUiBVikSVhmx1l6njED7l+zu3rj2l1PilnK/XbMrKxhmV1EXyBBcciE6gYHWheWyGwuSZqMz+o4iO9xEn+HEF9Vny0csWhCQ2E0pT6nQvliJk79+cG1r9y16ZZXbtffL/Q+YwYY1cQNRH7fxjWvvPCtW7YXZ35IVRVtAKK3AipnL5nM5kJZlQ11LVq3lcTxwwfX7byDTTeJ2OcSLzji8VR/lWJg0PQAt0p5JlB6fqZAfYae4prM8gt5njEDDAZ1uYZYwTrFYDpCd7Vs4kOKukLEXy4d4jH9afJe2+yAp9wuIv0orfvT0r6OBi8XEnEyMEON7C6z9FmsM/6BNa82UXr2Uza+I30pk5fm4pjp+4wZQIVcYjDQsH2uFEaDoQVG9e0Hb9n1o3+9aUclxbhFdD8TEnkYQDuBlvlp4VEUZ3m1Y0LnM/tGo/HMV5gsqWEajeZLvrV2131GJN5jgxVicO1OCxRVXZjV4QJeZswAcrlWrLMQ2n5FJSrrnFAMeMRqMpyU75nM2aiikWwV0MdkJjFiFAWPy51SGb1Ov0dC2QwQjyKgJrGNX3nSYjUVi6t0FFnobVihKFmGVWs8w5/sUU/bSdGmLkbChIjmecX09ZX01RZNhqUsE8SKx6L5mVBZa0d1vUS5U0HEPxLOZkAybVXJCHdFjZPfLtEYGApEYTSlvpvrXaZizl8y4wiLYjZGFGUJ6mY0koDFaoTNYcTFS8sQDiZYlkQie9yIhFQya/LD4tsD41GYKS3CsElnOdkmFIxOvqSfRHXEUIq30EEYJePQbW3AUh7W6y7kPiMGSACjKrFxXTTDIZABk58RRsiVkFkPJznztOIxuScx7k+gr8eHkf4IRdhAaU2Lszh5QxJVtUVwlzo0ZNI+MJZigDSz2s0QL2Gj6uXCmC9Fb5KMEDBEhsWPBrWXC/hJjSanw2aoBu/qV5fCoN5M3b9ZUbGcVlgbhYifWG+Hy8gBZot9JhquC+AdDOLY4T7YLCkCM+v1Z3FzLo8ZtY0ehNO6bzSmJERvk3uXmfcOpWgd85KxuiipeJ/j3cGYYUeZo+aNzf+3cKo45SCbylo2GF732qUGVX1L2oq4VtU7KX4WznKqeWAsiVAgSf2bavx0/OFADEcPdgGcdVANNJuQiGjxQZK6wjiPoa5Ru5IjSUrUGMqrsu2C9BFJEoboAZGUjQ4HJaiCi1FiscfGscS0KzgeW8RiXup3vIFeCZ+f0MdT6J6XAWo0PggS3jCnGDXNzil9i0sUiDGMU+dN2d5PayuB0JF3urR4nnEhAkE/fXUCpeXF8JS6yFQTLyNMJiM9iUKfn0SQBi0XRIIkIBJiyypdGhNk9otItKiGuGWBTBfc3zMOvzdMgU0O5uLL956XATQ1A+LGdcnK7Sgfttong57c+p6uEep+SketVjMamivgKXFpxOa2lXcDZ9hVPGngpEwInYwGATGOMuP57IG010F3xwnFMCMG5FXix3beHCD50Wg4FY/ryEX8wsGkZvVj0ULsAfp7/VqX2oZyLOyYg5KyooLE67hz70KI7v+lzu7IcCe5jfO8GxIYyFM8pSivBEgrGpI+zkCj3kOIHxul25kIUZMUQwODkamSMDYaQl19OYQBnxZEysoqnZokiLroNuB8+MRmCCgq1XgGUJABtPwDdEsTDBCfPkl8CnOELs/myJ4pqSn2uFCTQTyzQ1i8sgINbcVwukwIhGJIcpU32BfkcxxDHwUx/HEQYX92ICFMKCTy/tGwZvjcpfasNvoqcsuO1b0zoD/l2vI3VAdpVSeq4rH8Ip+glmjhaLql+PLm1mrNcDncJqy6uxm19CLGtMGSZm6GsAL19P8Bxv0Dc8LaXRhwYucQRnvOH9Po0WI0Es9igIYYGE3fz3srKAEUosFEekkqWMwWhVZ9Kj5jjgbEacxl5i5dXY1Lr67KInxqbyY8LCa0WFwYGA9TacNov7NaY8CxFwcQp6cpBB4yLxKOMR7Jtg0ipfybkfgL7rxGUCoYUGhGRBd7C9N7mTMtbZzU/0xDJWVxurQ1/zIHl19bfV7ipb0OlS4bPPYUMZ56G5beUwtXRTZxelu5SygtXkGYnQkiGaK+mWXTPRdkABN7Ghcl9heQD7lLzRrRdqeRzyZmfqd2v+6uJrQwfvg0UF/sgJkuUcBWbMLiL1Zr9wvHpcxYAgqrgJJCokuAPoh8ROt1bZeXoW3BZ9vMqSmyo3uUXphgJoMXrqvE0Wf7pqjD2eEP0eP9EOORUQz4z+hDAAN0xnCuyy6/Zt1GxRB//sCelzsnKvM8FGSAqIAIl7i/mYCNa4MlV1TNpOm0bYoZOEkKTNYSAq5KC+qXFKPzQMquHT+3H8f73kSAhDucDtQ1NaK14iqUVVRo7U988CFGBodqw4PYAtW0Zfm1a7dCSfygECMKMoCRy6BkICTgsTtTjFBp8Y3mbJ3TvsqfJatqYZSYdRbATr8v3kGHpuUenDrUjT1H/qzNdkNzI+685UvoWHYpnGSCjSG1fDsUZ5ySZlx3Zxde3f4y3nx93wYy4vblV6956MDe7Vt1nPq9IAP09YAeWAT8jP0ZZIjhy6cGTS3ZCxn9A9PdI/sPI7R9N5JDk17LPK8F1msuR6C+bqKrEPPC2/+tGdwvf+0erFq7WjOYLnoQWYJ7Q1EEYpMMq3c70NhxMRa0teLzX/oCfvnYFs/Zzu7frLhmbfubb7z00ARiPuQ4scmqa1q/Gksale95yuyM9kyIhiXTq3LVNrky01uL7tc1zpwBycFheL/9E0QPvg91nMtayWqkr8TAMAyv7qPUJhGd14pAIIj//O6jWij98Pe/hxVXXI5mriviHEvvWAjjlBR5zoQypxVFFjNK6FXcRUVYsGwZRr2j6OnqXl7fOLerp/vUEb19QQbsP/272PK2r/2by202F3ksWhxgJfFmXrkwb3k5POk9gdy6Ke+xGNRIDIaSYsRPd0v+G0d9w9jr7UOjzQkrAws1FIHl+CkYh7z46d+2o/9cL777o83ajDZ6nDg7GoSPMUAhEMItaW8i6lTqcqBl0WK8+85B+H3+2+sb2l7v6T7ZKf0LqoBUMqDoi4QTLfKs+duptEsVrXVBPmr1WT9mGrnyEthuvAq9zOje+cA3BbnW5H/6T6OI1vcXVfNRa7Fj/543cCrsx5fX34uL5rZARLvLG0CYuj4d2GkTBMZ//UeEX9sPY2U5Gu77Kh7+/iN45FsPcekdeJzVS6RNAZKkiqAq/ZJ7Ox/4mef7NNByxWUTxOv9h2MRrD/9Ds5FQ/hjZJzWvRyr1tysEd/j43rhPMQLHvEi4Vf/jtCLr0INhBA/cxbRx36FxooSrLvzC2yhdNAobtDayk8hoE3vy10S52vrIwN065uvfroylyt7SywSiWA8mcBjI59ggF7o8xywRIhCeKZnmA6n1IktyYQk3w/ueQVzG6tQXl4qucnbpX5aCeDc90kW9/ygaJb4/O2yWxw6dAjj4+MThUK8vqX2viwqCB3LLoHEBv1cK8wEZG0hYL/hiqzmycXz0dzczCCJG5RLOygEym3SYFobwPo+bXFB36pnc7Owpl8k3S0DFOOT3sfL1wzhXX+n7l+p1QnxDz/88ES7OI1hODxJpNnqYCapkcEOgxBCLL03MNHhPA8G6v2Bm5ahXTWjorEB9ltXQcK0hnAUA4E4du14DcuvWrdyWgYoSvJmERJKpJYALfTN4EAUngY7Ph4Zxxzm/AoxIfDHFyHXUz0n8fuhrgl00WgUoRBz7RlgttiYBXJqa4MLEX09GDtx4gTG6C4b7747AysNNr2Dk3g1UJLNBVVADi0oimGFNJQV3nTgP5savOipMKGgoUpb+5vL65jKpo/hJbOeS7z+rXkXL9DcmY7vVwP7sPbEk9q1y39cb5Z1t9HtCYiELV26NKtOfxHDqoFiyM8AId5mNa2vaUyt6kQCCkEklMBoXxi+dBJDBvvR8Bh6/Mz2ZERn0t/SPl9DU2Ww4BZ7Gfx+P0TvC0EoGEA0zfzT4SG84H1voumW3tcwxjR7Pjh37pxWPG/evHzVGB4cSpWryc4pKsCTGBsUg2F9VUMRQ8+UgMSYobVz5ycTaKC5iyP5+DgGPwng2KEh1LQVYdmd9ahocWKU4alcAlqsTuOT+ModcB1+H0YSvqm8GcwY4NcDZxCQRUYaqk1WPFq3AM8yCunu7NZ0X8Q6oE4l9vjZE1jWvFjvqt3DtEdHOPuLFi3KKtdfJHSeANWQzYBNq3c3q0r88frmYqa9TdpBB2mcLx3GnWFtTeBy21HBzc4gmXH2Iz9e/PFxXPvPzWhleKyDLsIarvu+jtKf/xJKKIy7yhuwtqQahwOjDHjGscThwVJXidZtR8CL97tSdkL6t1jKUZOwodeYMpRtSgkMp7rx9genUTOnDdU15Wh783E4+xleWxqBpT9DjOG1Oa12+ljEnsiKUQNTvDNrWi9ru3drTaOro6LOoa0CxfKPDoW0TUkn1wO5YJCdWTKUzRgiG1Fe42Bkq+Ifrw2ghGeDSsiYXEi6ixBZOB/WY8dhIBOsTDM1W524xFmiRX96+2BVOfYPDqC+uQk1dbUYPvMx6s/4sLTtUqxwt+L+2utQ29oGV0kZhns/QeuBJ1A5dkrr7kn4EKWadRfNQ4J2Rlyj7sXOcf3wzNan4R8d7Trw+t82T1C1ad2ulWx0W10LA5MMKTGRSNHzfEC6mZdLZG2SNM4t4lYW8Penu1D/OXfetUO8sRZDP3kEtv3vwL7/ICwnP9bQq3YbIlzBhVZdjYvqa4BvfJM7TIfQxrKeE8fQcdnVzERVZg3FXV4JucqGnwcy8kC24RTO4WBEi1EkjJZg7dh7H4ArQxpgZasgmmAApWVT00XFU/Lvsv6XzGs+GOoNMq6OY829rdpW2Yl3U9FXHZfG/tEYug57MXfFpCrk4ghfsQxy5YMhJkDmVa/gen4vFs9vQUVDs0ZovrZSFqrrQNHgBxPVo3NXTTwL4ZJlEvf8wp+fkzWOL2wwb5EGGgPSun9bWc2kyEqyU4IgIxcW+hbVBMb0Q4zi3tcdQH1rMZfMZuze1o3appSPFWaeeGMIzZd4YKJ6zBTGB6M4/fqIlhle1HA9Ph48jDf2vYVvfjtrGT8F3UD7PQiXzIHN+zECVYsQqM42jtJh50sv4yT1n+eTNh/Zu21UyrSRLZt374bScvtqMWY6yOanLNFl5zXgi6KmKTtml3Z27hYPnguh6xR1ju29AyHIklmMguQNxgbDGDoZRowHKCxMpMqVD+L0MiNdYXQf9OHUa8MTGyQmgwnFtgocOr4Hx46+h2VXLOeyvHCmOOJu0AiPuSTmy4b9e/bi97/+DTzWBiy2b6heUfeNPx3ofCqsSQBPf9xeScOXD2RbqpAEyP5dy3w3Tv3Di97OcbS10zKnj6zIKtJdboPDoaD/g3H0vOvXMryS7TWSOXbeZbYFptsIaShbgOWtd+DA6b/g5z/8Me6nJJQxzL0QeGX7DvzvU79DWXENblvxdZz9INwxivBm4tgkdgw8cqYuubqaW9baqxRxH5CZFu4G+XkAob9nDEuv5SZHOi7QGmT8iC3oOjnGrXKepKL+l5RbpxyaEj2U0xwSVIlqhbnVJpHgTOH0wGEc6tyu5R5uuGU1blhz08Q6oRCOk/Q0f/rt05rRqy2bgzWXfRU2sx1x5jkP7+sTQb1OEetPS797CXdxMkFnQMAfxbkuPzqurKRY5xdh6SdxQNcpPxmXmlXJIgkkmEdsbJPDz9mi6xuOU8VmzgDBNRLo1Zgw4O/UMsLtly6FhMvl6YywtAkweuyhld//+htaxMcjfLhy4Voa1MuY3J0cw8mjXniHQ0+ZOBkdZWXZe/OCSHZjRQLEDQroGyTaS8aPdyBMUbdyp9iEBZeUaS5zsDcE2VeUrTVPhX0K8RndL+ix1FmDGxf+E/p9Z3CaxvHgvrc1L5EPSYKnUGLRCKJMsIT6i/DW8U4svqwOpRVOTQKFGYxx2k3cRvIU5cyOINQDKF2n9exw7sdk1tvs1H06//GxOBnBIzW0JxIpShotd+sst/+nea9yt0AugZNnPpTsPVS7F2aTDS5rKX3bOJ7b+6RWf5H9VubGSuDggasPj/biylVzqX7J1LgUpYNGUBUV0BrLj4ilnP/Rw1/RawHRm3xQP8eFDw+PoLrRQeNk14iWHWNJPExH/AWof77PTpSVOZoodXHU1i6YKJMT51bqeqlhMWqKFoP/xUIvFUSMx9f6aM+s1kmJ17yAuDMdhNAo9/01IM0SQsphRNHlfCDhr4NneX3U/XHaCw8tf759g3x9Z6NMNknHvNmBmqhrc2U7Bgd8CDKpmglCm9XKCJZMoxF+nZQrzUqGbdPP62d2ko90nvTB502dzLTxfJDMri7ismssR+U56ZrkJEQEMoA81PL6GUVigTmAyZIk7UU450jOZK3gTWjnDrPLuHfAPjFOjhyxk8MUY0yc9nSOojJ+PSo8Kj7yvQqnsQIlpjn0chaeNYqhiGdbx3iQSlWUbSYOpCkTqYS+Lh5sCI4lNMMnCiB5geH+AHwjzLBGkz5mrs+SJEkWlLJ+aoSUiXCWn8mzCL85RKn2cxzD5CLnG81DvYEmOT8soKicEYZ7kbAcp1NwLvIWKhzz4bS5MdA7xm17k6xhfMagaaspHo/5jx0cLm7m8RV3qVWz/nIYQmZVIkEBCXiqeLZ3uJ9HWfoDR5546aaVUs7EyREum9vFA8hsprI8UpMfxCuEg9y/p/+VFowNtvB/hNrlCE0hEEmhJ9MIkeN0AX/MqiRMV2X+S578fyE1/Ej/2bGmMp4lDkZ6OHmpwQdivVjsuRdWkx2RWJiSRLfeMwK72bZpy57rRk2haICn3404cXSIgY6Re39mugo2ZmgrgU+mIYun/4tDBiuJEx5lbS+h4RMPkS+okfM6mWLOFZhG55a/3rhHHh5cs3NUvEXuASg5iaoRrrWe/JEwWMbk82pR3Aa9RgjheG73eSPbqA5NzS21OHu2j5Y4ihi33iKxkOaS9faJROzdX+26dau8mxiV7U8k4zcGQn6YjOagqrodcg5XBi4MyYV4OkHI44uby2tcDC4mDWhu2xEedNQPLeXWTfdeyn+ZKwQ2h1mi0/VcwG3OlIIt2286QknoCCrRLaGAst7tLOX/GRgRwzhOBJ5Fg+0aFJvqNbRxVX1Cx29IqIk/hMIBIfhoLBZ7XmZS3seCjJT8g12/eOlGxesfemp0bEgToVB0XJHVI2eoaTri9Q/M9l1cthi7hDGubWxk4hdJoHpuUAKmEkrr1xmM/YAG8GgoOYSTwefw3thv8Eno7X9/eu9Xtur9TPKy4eo/jBqM9j2IhzsoLl+JJbRw1kfuaB8xGG2bkolwRzQaao8nEk/xLNOo6lSPnjvja6+mgcxUE0Esi6fM2EL/2IXcC+EY7uPeYDDu4xbqnkL4hBGs2yr1CzpWHKGW/UWeozzx3xt7s0eedUgppf7G+9eufmYrlylHjEb71q177tDWzHo1GXX71r13b5N3MTxJZ2wPyW2PchenpNyJqppSnDnZp537lZPkbjeZI9Y0DWIrZM0gUiVFtAF7aESv1Q9hS5nsDIVpveW8r4lnilsuqqA9iuFc9whtBVeSqtXHw9ArReSl/Uzg4o4V2/jBTlqkbcePHNiT2WcKAzIrz/e8YfkzzWaH9Yy0i8YjnHULIzAbDy0kEI4wA0PiS9yTGaHUf5OpWQygBb5WYUyhw9i4n/F7GBZmh81mK6UpqsXzZuI28Hh6KBR84Lf77krFuXqnz3AvbMFmiJQLjuv4rwQui9m2SE0k7XFER6SrlXG5ACOujxhITWwAZlp3iuYmSpsn8x8tuTbp0PuKy2LG3G5SzPZkDB/EooE+QzKZJZXaRz7Dz/8D6PwaDC0mnqkAAAAASUVORK5CYII="},7846:function(e){"use strict";e.exports="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAgCAMAAACrZuH4AAAAIGNIUk0AAHomAACAhAAA+gAAAIDoAAB1MAAA6mAAADqYAAAXcJy6UTwAAAG/UExURQBm/wBl/wC//wBk/wBq/wBw/wBn/wBp/wBg/wBk/wBl/wBl/wBl/wBl/wBl/wBl/wBl/wBl/wBl/wBl/wBl/wBl/wBl/wBl/wBl/wBl/wBl/wBl/wBl/wBk/wBl/wBl/wBl/wBl/wBl/wBk/wBm/wBl/wBl/wBo/wBl/wBl/wBl/wBl/wBl/wBl/wBl/wBl/wBl/wBl/wBi/wBl/wBl/wBl/wBl/wBl/wBl/wBa/wBl/wBl/wBl/wBl/wBl/wBl/wBc/wBl/wBl/wBn/wBl/wBl/wBl/wBn/wBl/wBl/wBm/wBl/wBl/wBl/wBl/wBl/wBl/wBl/wBl/wBn/wBl/wBl/wBl/wBl/wBm/wBl/wBk/wBl/wBl/wBl/wBl/wBl/wBo/wBk/wBl/wBl/wBl/wBl/wBl/wBi/wBn/wBl/wBl/wBl/wBk/wBl/wBl/wBl/wBn/wBq/wBl/wBl/wBm/wBk/wBl/wBl/wBl/wBk/wBl/wBl/wBl/wBl/wBj/wBl/wBl/wBl/wBl/wBl/wBl/wBk/wBl/wBl/wBl/wBl/wBl/wBl/wBl/wBl/wBl/wBl/wBo/wBl/wBm/wBl/////4qMBKkAAACTdFJOUwAAAAAAAAAAAARd0fvUYQZQ5ehWrrXJytLq/s86Lr79b4DeKAmwmwM4+raj7PNKhb0VBWDBEhu5DAFc53NZ+fYB4CsIq/eCCuOeBDTmg1Lh9E1+C1vxxBQXfRLDd1PwbAIVxuItpO8EAWf1ogYv7moEAuntAwNl6xYUxXtOqQQFbuQwwB8QdBAq3/xUIZOtVQTTBeGbJwwAAAABYktHRJR/Z0oVAAAAB3RJTUUH5wgXEgAa2OsrGQAAAWJJREFUOMtj4OTi5pmMC/Dw8vEzCAhOxgeEhBlEJuMHogxiBFRwM4gTUCGBpkJSSAq/CmkZWTm8KuQVGBgU8apQUmZUUcWrQk2dQUNSU0tbB5cKXT1GJv3JBoZGxkI4VJiYMppJTza3YLS0ssaqQsqGkdHWbrK9ogqjg60gNhWOTszOLkDa1c2dkUXYA4sKTy9Gbx8Qw9VXhZHVzx9DRUAgI2MQhOnqG8zAFhKKriIsnDECxrGL5GSOikZTIRXDwBjrCuXExScwJiahqUhOYeRPhbLT4tMZMzKz0FRk5zDmQt2fl1/AUMhXhObSLAFm9hgIszizhLG0rBzdt0kVjJVVEBPKShi98vPQQ0yqmoOhJgDMrK1jrG9Iwwj1xibGek+IUHNLa1soZsyZtDN2dEKEusTlsrDEvk93Ty96CkVzaWij5mT8KnACCSJyVB8BFaIMNY14FVj3M0ywwlc6TDSeBAAsQvZl6HikOwAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAyMy0wOC0yM1QxODowMDowMSswMDowMKDKy60AAAAldEVYdGRhdGU6bW9kaWZ5ADIwMjMtMDgtMjNUMTg6MDA6MDErMDA6MDDRl3MRAAAAKHRFWHRkYXRlOnRpbWVzdGFtcAAyMDIzLTA4LTIzVDE4OjAwOjI2KzAwOjAwAQBrPQAAAABJRU5ErkJggg=="},302:function(e){"use strict";e.exports="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEEAAABACAMAAAByderSAAAB0VBMVEUAAAAAAP8AgP8AVf8AgP8AZv8AVf8Abf8AYP8AZv8AXf8AYv8Abf8AZv8AYP8Aaf8AY/8Aa/8AZv8AYf8AaP8AZP8Aav8AZv8AYv8AaP8AYf8AY/8AZP8AY/8AZf8AZv8AZ/8AZf8AY/8AZv8AZP8AZ/8AZf8AY/8AZf8AY/8AZv8AZ/8AZf8AZP8AZ/8AZP8AZv8AZP8AZ/8AZP8AZf8AZf8AZv8AZP8AZv8AZP8AZv8AZP8AZf8AZf8AZf8AZv8AZf8AZv8AZf8AZP8AZf8AZP8AZv8AZv8AZf8AZP8AZf8AZv8AZf8AZf8AZf8AZP8AZf8AZf8AZP8AZf8AZP8AZf8AZf8AZv8AZf8AZP8AZf8AZP8AZv8AZP8AZf8AZf8AZv8AZf8AZv8AZf8AZf8AZf8AZf8AZf8AZf8AZf8AZf8AZf8AZf8AZf8AZf8AZf8AZf8AZP8AZf8AZf8AZv8AZf8AZf8AZf8AZf8AZf8AZf8AZf8AZv8AZf8AZf8AZf8AZf8AZf8AZv8AZf8AZf8AZf8AZP8AZf8AZf8AZP8AZf8AZf8AZf8AZf8AZf8AZf8AZf8AZf8AZf8AZf8AZf8AZf8AZf8AZf8AZf8AZf////+EMc0jAAAAmXRSTlMAAQIDBAUGBwgKCw0ODxAREhMUFRYXGBkaGx0fISQmKCorLC0uLzAxNTY3OTo9PkBBQkNFSU5QVFVcX2Fiam1ub3F0dXl6e31+f4GFhoiJjI6QkZOWl5iZmpudoKOlpqeorK2ur7Cxs7i5vb7CxMfIysvMzc7P0NHS1dbX2Nna297f4uPl5ufq6+zt7vDx8vP09fb3+vv8/f66JvsWAAAAAWJLR0SamN9nEgAAAl5JREFUWMPt19lXEzEUwOFfW8EFARGpKKioqLii1h0VXEDEBXfqLopWRYRa26IFd8UNEGql97/1IaOn25Dp5FHzNndyvjmZJDe5AOUd4Ukpvk1Fu6oAYMsncdu+BgDWTIj7ltwEDIhJG/axQcxaM4cNhU5OGQqXOGMoBP8F4VvaTIg2UnHZRJiuBzyPDYTrANoVN5uwFYAO98KoB4Cn7oVjAKxy/ydTfgDOuRfuAlA6JiITbasDg8ULuwDYKyIz24HS+8UK730APBSRGAAlfUUKXQAs/yUiYZWQS/uKEmbqAOgUEfm5djbCTngEgPetiIgkarAfiJ2wD4CA9TSy1CLuORa+zAXgzp/nhD1hI3QDUJX8G0io9YXvtkOhAYC2jIgtUVgYUL1jmbH4You45URoAaApOxizDuqSkF4YXwDAldykZxELx7RCDwDzx3PjzxcpolsrbATgQP6LSBkA+3VCXH3pSYHV4wWgRSe0ArAybQcQ1AhJNdqz+YBKnNRNaYSbas7yLlc9FlAZ1c3mDgD25IavWkOoGNKtqDeqZ8gGqAxrV3U7AP6UDfBMu7NStQC0Fwaq4/rd/QAAz+uC07hk2EGG2Q1Ac1bsmjULNS8cZLkPcwC4kRl7N08B/pdOMu1pNWPTmbFeBdSOOMn26RUAHMre1QAsG3V04vSrz0WyOx0E6l85O/WOALA+p1O69+iFSYcnr0pvFw1ugyGA6u8m98nz5TQOGt5Ii624gv/v9pZgXiWZVmonWGcobIN+IyDuhYZxk6q5CWDzR9fA550qHZQdH3JTvf+InKwEfgNIA2UV0Nw41AAAAABJRU5ErkJggg=="},7238:function(e){"use strict";e.exports="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAIKADAAQAAAABAAAAIAAAAACPTkDJAAAGaElEQVRYCY1Xy24cRRS9/ZgZP+JH7NgOCTE2CIiiECFZwBpFrPkAWPFV/AY7VkhZIMQCIR4iQQRsOcRMYmNP/BrPTE8X55yq6umxY6A93VV97617bt1XtZMnH88645Xw5oMjbzxqYxLf03O8tCYXeRglH3kaIVfxwxrQSRoB1edj4EEmKoi8CEDjIg+jNzaAyPDaPK7B6JdFZf8KXgOI8lHRZeCVQQG8kudmPLiBlsuM/wKPoBwbTUuaE7hbZhr9PGm0LMkbZriTBkeozjDHu7PShgd/WtF+5MGjcTAkJ3Y91um1m5bNL0uJFERledMsgzh3bEOzsoRijK60xDGNSs8jGzQrBhAbmCtAwC+7esNc79DKw7+8XPAIzKQBXihfu2v54g2zfleLxJOyvjko03XOlaP1Xod/p07clSxeBl1LZ5esPGqP6FUIKAwjGsur5rpHWuywv932nh12OtZoNW3l5nWbmJ4KhmFBa9JShoCu582QaAQtJ61h/ae/mDvdD2swMETRKI3KgWCtLGYK+/fNx1vm5l+x9U8+s+2vvrBHP/xotzfu2sREy5pvvm/5yjpEIUx5XtXoJw5DevDEht1oAAjICckFcFZOFQKFtiwk0O2eWWe/Y6sb9+3q2/es6J3Z/sPvrb391NZuv2HDoz1LWvDGsIcYh3vYR9wZqnAXZ+CDRnsUYpjLHKqBk64qEDgebggDsGLQx0KE4MXvcGHprLu7IyVFgaSDwrKzY8MSOVFzfzo1q/did9PcyZ7k6uCaozI0xiqgByI4GQ5KExCnZqYtTSUF2tAW72xYd69t033sHAuy2WuWrbyOHWP33DF2XvaQO0jU8uTvl4Nj52MeCJ6RBypLAWZZhlJu2Dv3P7K5+5/CoNQmr1231Xc3rHj0AJ5hTcMD8EK1jrsICn1HHLlddLkdNOVAkKVBWFflABcyBAkMYGwyZO/xl59bOr+E+j0xOz1E/KJijl5hzH5f86eWLb7mG1WD1YDegTA5eGew85Nfw0pwwKHR0DfuATAsmVCiZMtrSLRJlVgKJVJ0dmTF88fWuvOhB0lpLAzBo+yfWH/zW2utv1fRPI+hXbRB+2fIoWlR1wCeDpvxHgguYkYjwJZeWbDWWx9Qs7dUE3qob8XBtqUT0+JFcI5JcxJAvopkgQyjAtwZPMHkYteEZ1xxincuoh0xPiAwmQy7YjLykps00Sv8BUWqFDIDgyN1KWnRgvVCHq4gQz0JzpDKAzXMVEIhHg51zSRkPV8AJ0iwOir2awXlwbgJ/OkK4F4WbHRH7wGM5AVMGEDNgUBgGsDSoiIpIS/wMdBAh4PI00jAJTk86KFLwqA2HHMggBP7Qg4kDEECcB4+VFgHx5yZ7dDlknyUBzTIDdH5SuTI/hbyeMZvgp0QNMqXZwewFHqps1ZNeZUDjAsX0ANAZUdLpqAIxypDo4YzgCKUZ++3B1AEVzJXaCCM1rk/OLWis23ZlSXxVT1o2SlKr+y90HHMI77u9coDii8VhgQZtH+1bOFVlQ1LJ52cM5tdxmJn6dRVy5fWYSw+OCjPC0Nv+zvLF25ZNrPiDaOrA294/AxHB3qJvikoDx5+oQ/4F4KrlNgglteteeueV0RJ/PzF8wCpQ1fGK/D4paQK4nsEDzJKQuhP0nEPqAwlG3bukygcTFKMRwCQHXQ9Q8VLQH5KQIEwd+rgYa14nMsArsULfukYePQABQXihQRBGi6Gg/lwHnyMJ0kKhwlB5DEYGT/ryAN91IjkAVDVjumBAEId5xSN8wITgyqk7h2tJQO/+DFSywHZJeURXN2SB1KuzOf6MXC+QhHLSpfc52WYO2XvGFWya8OT5z4XEA7HMoRR5Wn4RlB/gSdoNx7jSQhC7Oeuf2zFi6cSUouGEinil+3xczsbnHgQVo52jRoP9d3f+lrrZDyRBIahMYmvqZ0KnPTxPgBCebxn2RzKDTXd/+OblyqihrLbgTeAyB6AA0b9A3NpRxgdQ4nvCz/yHfOjJ9D/rKZTZQhXxArAWB62rZxZUA8wAlAJ22tUisOIyhK4tqRXgovV8TBXFQVPjHtg5PboER+CGjgJPDWL9kOc+/wvJhqHSVQa5NWAyKeLow7NAy3ywkiWZDWO5v40lAIPPqYw0EfgXIjfBcCRwhEIBT39MnDyQxn+X3DKjRRXhhGBYHUe30G/FBxsLvoHJCM5JyU1x+sAAAAASUVORK5CYII="},8606:function(e){"use strict";e.exports="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAQKADAAQAAAABAAAAQAAAAABlmWCKAAATC0lEQVR4AbVbSY9lV1KON2RmZY2u0VV22+4qm8G0utVN00ICsUAIiV3v+AeskFjDig0/gD0/gQUSWyQWSEDTom2QkNsT7XKVXVXpqhwqyzm9fPke3/dFxLlx38t0tVriuO49MXwRJ+LcM9xzX3rw8MeX55ZlUIhGQ5b0IIjGEw8mxao7PuVGu8B4Hbxklaa74OW6rxucqSu4GuNL8FQP2Y4KmEY0GpKkq2MCJcct9KlOvqs7TM+m2oePU5P3oKCqfoJe9JFBUH4m3mMXFDjvADliSyAa7SylcqZaXGA6bLa7jOswv3LydHFmMuEfVQucdAsoaMmIQYFO6rAZdglDIqHjGp3OUheGqU91a7ThQDRaLTtf7Zu+YivNeCtfaDrHP2+j0BlQ6rJWCP3kaRtTIBxE7u6UzmnN2qteYxQ3+SIOfNOFA/KSha7pgxes0vRf+VNoiOSUtS4JgqYseMGWk6cNOgD3gmt0GqdOdYdNdWuk4TqM+wpe+kpHgJIv0ow9sBF8Ly7ayC4w4iVw+RIfydMXDaUnObBxcxw6VstJhTLbiHoZF84D3musNpxtVD+FHoxXbLC6ZoOVNbOVc6qdPwfe5YNx1MARY/OZzfa2bPr4QzvZ+ZItRKIl+exUteUNjh0ZYBlFJBmQAGBSnPIcAou8fMSNupVVJMMkcNWkgpacSSkR1EwMdvP5idkMOzRrXHMkyCSdn4GEbLJn86MXLmdbq+u2+mu/Z9OvPrXjB+/rQWaYckoMr/IwvAMkpDyI5IVNBj25WpKJoJmcnkpNSDTlq/SARDxwTyqTQAKSk5/a/HBitv/cE6cNY8mmxVMWRMoX+cmBzba/tPGr79hsf8tmWw9o0PmqeNJoo5sCZyQ/evXbtvLmuza6fEO+9ATY+5FUSw4yPaHZ1GYHR2Z72/4Ea7BJK6gILGh0r/uPwJKVUDJXN7nguDWdBADNbfb1pq3c+U07YgdkRy7iI98YAWGcPtgWAKu/8SMb33nH5i+e2cnGZ96YdLyxFLvagCu98YT1fNO0s/3lk+9s1DZZiYqc5PTAhldexRLPTQ7TKDGsdUkgGiMgGOhagWz06ltKfvbsC4jTCcgG75z0Gkgn6ZewZhN00b00+UV/4uGw+Q3nyQcr2BhT8ASjkeCmD4B4ToEsIc8OWXnjXTz5TWjPTv7w8ND29/cxC2Y2Gg3t4uVLmPZotCS4lHwK0N5S8hkLa8YzwvPhAoqFUesMF0gullBON+/jSWPdYFEyUacACyd3kfkJME1PAkU8bvh35iI4unTNTp49dIM0EofGp8f25YNHtr21ZZP9PRuipwcMFo3evH3TXrv7FmIfeUPpgY0OgTl/UTvCMJOJum1rCNqThc8hfdCwlGBH175lRz//50im6JkVMdgxuMNolyCffpJmjYKInFiqNX+gk0FgwBxPJvbJR5/awd6erV65bvf+8Md2cjyxzZ+/ZwdPvrSvNjbt8ODQ3v7eb+VrpnwMzl20c9/9IxusrcNLNhr+0z3rompBp77pBja88Eo/NulwCwx3HL1HkD8jeWLLCOiMiZ9zeLET4MgLPZk9+PyhHewf2Mr5S/b9P/9ru/jaXfgf2P7Tx/be3/6lHe1s2e7OC3v88LG9/uadCAhryo03lHyLkM7cJSkvlc+gl3QDTMq5TTc+6exlh1vaKwFsrxhdTUhd9Rl8jIDO2DHgj7F4jDAEp+wAorFNY7jv7uyKHmKonrt6CyMNWyL+W795xy6+ftcOtzdtCLvNxxt249Y1W1vH+wDMZ3s7vpy4q3QpX7zRh2FqsePn0yN/AKpBYx73ZMcHNselIn+4Nb9BI65uBACZyROnyw0wAsKgYZyfowM4B+fpGeIXz1/gRQUSOJvsPbfJi+e2voYEicGcW79+RzoINFV2nz2zm29+S+rZ8w07+vBfbHjxWj+5kmy/hyIguPYQSAQdZJM3HkTSjJzrCfmUJV06o60B7ckHeH58qBW4NQpigvmvIOFxfnJix+iE8zdvq1PmJzM7ePaoawyY6XQavM/62c4Tmz1/4hEtBsXFEAHr4vYVZ4DZ4a7Ndh4rjKVkKGh+Cg2h1gBOAelDR7okT1prwGLyNOKQG5y70GtgmM4Uztw+/vu/sx/8xd/YCFvTwdYT2/wQ799qEcMZI+X8jdvi02x0E7vD5Vu+yvOMwIQZJJN35/Ksm4zgBh198N4/uNuQ9ZIimAmkjgRpnhs4ApKnbCF5qsanJU+gpgD2dqTihgBfvHzRNp48hXMGNrO9R/dterhno7U1W71wxW59//dt+6P/suOvd2314gW7fP2qDaaHHhDsV+/9jrZLulSBzGs+MQSs+Y/5jpcXLcLgT1581ew7GxgW20bXZLkLcCQRpysMKg1Vbw2oQI4ArGYwhkXYXr5+3dbXH9nh5MSuvv0de+tP/tRWL11Vh4ywvX33z/7Kjp5v2eb//IfZxi9sON3qAoCTyac/scH65VjQ4F+Lmy9w2EuVX7bVe1quiTi6eGpsgig5UKjZoVyo5W/xyRNMN5C3NcCBcuNG3AXw4iJ5Ew/s3nfetfH3/tiu/eAPtANwqKvA4QzvA2N0xJVbd2z69INiy9aQ7zbWCF6g/SIRpXT0UvKJp1GaVDxdJJ967gJj7kAhYFXo/OCiNaAFVBrgEBxgCnQFHvBvbQ0fKx6+b4evXLGV196mV/ilbohdYRvn8A9s/uC/sQ3su2kGlo4UCM1IRKmYlKc68Qoy8ahTT1HaVxl3gZwCiVFNOICB9REgphPSIdcATQEaEU2McBheB8/t6Kf/aEc4ca3evos5i2F8tIdj6I7Nd2POyqz4DDfuJxwtYl6WPJ/HiIsnrlw8+RrORPHSNt38DMMMUynj5LpCHM8DaguqkjxxPgJIZUyscWkNGGANSF3VyxuG/u4GnvpGs9Vm13Agko7GxWeSSoTbHoKP3aAl8oyJIGjoVt/8oQ2xbujLEncLjLRWFvwPL1y1yX2sPxkzOoAdlQciJZ/GtEUsGAElUDl0r+oAHHA86LBylTNph+93Q+7ZfAr8EsQgtfjgPeApEsFUUiLYAYbnkQj1fGpMpPkLIiq+LE1+8e82vnHXxjj0qEjXDIottGl3Dv4zecrYAYhlPnmB9gLESpfz/UWwGudQCjsZIfDVd36kRDQEmTAc+2sOHLMkHuTw0nWbfPJvNr7FRN7o6TpcGFQ7PnGWssD2jAu28wM8Ole89JjGxhHAzpa3TpcCyLtFkJYECqwbnl6sA3EgGt++h6eCRLLIJLCUFZLscP2Sy5jIgo76Jqw60OpcGOTQbbhiUs1FA69RKF/hMHcCNk5R1YnHqbIJKyBoLYR1J0AerQBz1pMXhj44FYBSIs1Qosp1NG1YOJ1Au10KIS9kjybDf5xWQ9iykNcUcF+Od5zoGAU+ESFfAkCk12EthNQjEY4IFvmhUZRCShK8niRovdUtYRO07EPzlZ2QqzchtY1KezDp3RdV6D0/XwSXc+va9hEgnlaloUyYR2J6o44dIJJMlEJK0niMD35PGK24HZVF18M2uaTeBhcvLqAsVV9pD8Yxce/mPB6YXod9FMqHbHFjHX5OmQJUOqi9CwR4jvP6S4e9AnF7klqFc0FNnRRiWiDBBe/zWR0QbVdTx3ZtVNtcP5QgP90vLIw1eeaJR4TCRrKhfNoQ+dsg3wVQqM8pkDzrLGlPYKNB6knG1ElF6rPu+Qghp8AMH0h6O0EBnmqL9mL9cGSdApDQJu0iT4yAlFAJOlnWuQtI3F8DoO1K2lBSafJ8AvixZCmRRZz4Tqj3eNpzHejEEIDp8S4ilAofAc75d8FcFItdybOMgOKVJEBa9HAibMMeQ1mfrty/34tZrzOpZZvaCWIhTGzW6Ud8EYLUGyLq/g5CRRpF3fjUhYAVd4ER3w1SB1mPxqYhhxSysNLlvL4J9L4OQ37WNEgfchR+WHFIsugHCtTuWiLdxBdhkhEovwh5gSJ1aQ2eI4sPana0i1+Fv7DpzueRA0FcA9B+2i0kT4W/ChNLkK5AsypTIHtO6wJefZtT2YYNaZbGgohX3tnhC7xBXnF93oVzsBJhJ2HIM2n98AHcBCfP2T5+Z0QyHA1ciNmZGhlcXLFOdO0BRnfuEkQU7kSYhk2e7aLu3gRTSBvQ3ItzCij58DU72PV3+uCrjiK+fs7xXYBfeGeHz/2EBn+TBz/TL7Z4ZJ4I5za2ufb1hwGyMA7FIk4dMn36cZFBiaeqH2PO4U0TtLY+rfY4f2zfl02LS1shfiA5/todyjdurOkqCXEhzIODtiF+FWKhDmXy2X/iE7f/ZEa9MEqENJ5gJkJw+CPJZKdPIhH5wo1/CMFkmAjWCk+EQxZH2y2eCPF0eSJ847dtuHbZpxMT1nSDvfzIu9/AD8/jRPjwp50QHc71ZA5Xjg+7sI3DUCfM5AXGU9LHygBLxkQefwRnKYRjdhIaGaydR5A8DSIJ1giWw3fGIzP41beQCA86oeufCDNAj314AQepz3+CQ9S3bXzldRe2JiNel/Z0A50IQ8EYeY7RQkhZ2KUf6P28S4Gu0BTaRwE2C6yoKtCNbiIo/BGCJ8tEMcdSyTrckOSucfjBP9noym0bX8XRtnYcAVmKDUU6SEkXB5CmB9HoMC78AN8ZVKIdnQi1E4VdYkPfmwLS8ZZBgtZiwyeMr8DZSat3f4iR4ctHF0x4jsqDoAnetnS85YmwKtmOUF0dLHEcPdTPF98i0yaxC7U6INshllshRpzaStuib6/CkhFQlAogP41V3dLbWXjOBhhUpZFMfz8v+oqTXQg4bOGEi6QXyBexwoc6K27b0XnCt3eBANT8IAIavU3HeRGXNBRc2AZ5IKIORdOiBRNE4wGoNFk8AdnQmCX1WbsU8k6gtYhTi7sFDTpVopdlYe+jgDDEj/OARpPYcJK+gB/KhgIJcUs6g8Gi130cJW7hqcgxb1HkJxnUwOttUImQPxtXrETybwjqR86ePv2ksPCecAqwCGoKBJ/iyC/eBOkFGioFCBQqfxfwN2Y9IarYKZlJQCFoItHiXcmAeqOm2hRcs5MM7jhy2hQo2iX7MMhK0yfwWgNyYQxZJM+qrQG95NmALp8Ci78Q6W0sGwuf2R/J9oazEmGnoSwFvyhIDOScy1wEc8051b4Iw1U35GmKH0jaNkjfDorK14CzkqdrPgH/UxVyKLDUqKhxVzowwuaNifBoy3fzXlk0hFIi3PiPdihtAV2EJ5agopMdecmW14BMnvrTp0Ai6KCuASFvAS00TLYGknwG1FsICVSAQvlNfCfPxUztnYWl5ZKu86H3l7IGZGpuo8NQeKATXeEtaF8D8B6QlpTzlZcloM4kX4RBah8miJ3JgxQNC4wq5xfkPEih6A+d+LqcRbbhgFU5XxCrEyGxAWlmyavGDf+++U0QAC1C9UjM9rgwyUm6zsaKsJDZeTMEN1zHibDq6EI8bzza+vlijuPtdOe+dJNH79v4gCfCcpDCrjKf4eLuwnWChS7Sd9T8sDI72MoQurZC370J1idMOgAatnwTDJ41j7Y8vvbODQ3gQcz5FYjJoLOmTz+V/eQLHG0zEf49EDuSCXB9UCILCyXbZCzQTZ99HDGAp5xFdTCsenIChjgc4VemRz8j0+ELrjsMJSA7QjyQDGzBuX4c/d9/hfNXEDh6H5h8cqKZGM8OpSExTIRH21RA782RYIMote7FEsqqT3DKiv1gvK7kT3Ye2Gz3i/ALYGKj/oYpkMFg7d7HX3itrGMOx19mwQv/1me2+wQO0yPxyw14gyEXNPAUJR8ixq9CvvrVCMR6zZo/1OC3igF/ryDP6Ym1QjrSgZ0f7ujJf1PybOOMKdAPgP8Twtrbv+v/IwL3ZAXYxyjgTKRXg0k8iQh6qNoT6CUDuX5PUIJIDMnNY4rklJmf4M/iMcpy2rCmTjXWBY5CbNbqS7XNG2NgabUT0QEhZaWr8nja2w8wdG/a+OY9jIZNfw9gA+ptBMyzQvS+gm/J8UnFU5EMfrkTZMCkJ/ieJ96TaLqQ+atwSSZHRoS43PFxtmnJAtiwFKKkD5CxBlCYV6DFd86OH7yHL0HPbHz7123Ecz0TjkXO5z8XtEwm/sipJMoVW09G7nGTf7RJ4lSaqtAFrAVOvGQLejhquQmzqIdRA5B+yTbYsBHICUbCyfbDLuAEsLHAMK5G1yAYywIvR7KVkVh1RvURqha4fJQ2Uv8rJE/T7k1wIZlkz0qmF9CZyTNQv745+Q4HynuqJRq85LyhtOBIS9CJgu86knqUJRvKWgdEa6wAbFgSkslDRycg8F1jFR+NnmZPgyYvODUTumiyBUO8ZEE0+xqvAO47yJ5NT+YMl1lhPKDqDPLSSKMX8JLLV8VDkJ1HkqDTfFW7JVoC3txWNZ2gFF8ZjmTZTmIaWETnp8ixkqHI4f9T8tkRih23FjzbDV4xVDqCWsSGOJP9pZKnj7QLsj70WANq40HLsNDZGuWnBS58X6dXZeEjgkb3cX1/Z2BDfHry9EcAStaV7smCier/AMJqTt2MKqTzAAAAAElFTkSuQmCC"},2032:function(e){"use strict";e.exports="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAIKADAAQAAAABAAAAIAAAAACPTkDJAAAFG0lEQVRYCaVXa0xcRRQ+M/exsJTFUgOCpawGLU9taBuB1kdqjRQxwWhMQNPaNqExjTXGgk3sDxOLptb+ayRVafyDRVJfNAImPtpQCdSaKK8mDW1poU2BQq0sLNzde8e5d5m7d+5ddhc9f+acb86c883MnTNzEfwHCbz1dDnM+ZpxwJ/qu3NbE7wFfVKKZ4frva/7lhsOLWcASyyoSiobNzM6zFQQ8kv+XC6RuAgEP9j+Erkx3CQs+D1mNqqonlXgT3sAyK8tVhjE4i3Dck7hTml3wzmuI4IRlYAxY8X/FZeYaBDMzAGx5h1AuRthcnYehMnrILV+DKSnHWDuHzONTkR0iS9G25qIBEhFRnbgobU/ibN3c8xoNLHqLQCx9jBA2moT1gkwwbN3QW7/FEjbcZ5IybZO99nWanQG/ma+rHUQUOoqmvHUWA3GAvMBNTvPkZh1WgkwDFEiLp1IyxEGAVqVoUiPPP5+4oGmQyZIFZOAsdwz09/TtDJz0EQJ8JvHjKVmmL2NRID5GFtzbB+QgW4GAfbm3ZIzsp5l22IQUA+9Ug9X+g+jxVkTjQDZWgNCdZ05UO3rArX3R8AFJSCWVZq4lYD8eyfga4OgFZSCkldm+sgXOgE1vQswMRrC3B4il5bXJtY3fW4QCOxapwoYYWD7fLDZHKwrCwcqQRofASTSxVGDQN4+TomUGj6MgHB1AMT9W8xx6LEKmK//wrR1xdVKt+R06PtAqenznpPDiVjvMJLTVttYDqItebCxDuSpm6HkhrMIcO2irnEizM9wNulth8SOzzhs4WW6orsbDIxMjyfoCg68kLmZeaGsh5kabvu7wvqipkUgAOPXHX7Q84MDI+lrOAyrsryBQ2wGIsSGUJOuiEMmnAQijOSG+Z5JWmdsAYfaDHJ/uBTYujgTI/NAhfFCc3HDmEUjAronJgG8fqtlSEglk2NO7KrzHtK8hQ4/OxCbwLadALZtwEq4+rGAeDZcgg3M7QGFftSxJCYBPYDqzefi4AU/Z+uGZik2Rufzexw+kYC4CBj1n9YIUwR6FH3hsq6XXk702T9Xy0FLGTRSHEIvH3VTFQjdbaazureM7owGrgnniSD0rJOkFNM3mhLXCmiX+0Dt+oaLg+UEEFxuDmMGohVPHBlk5pJtcqfvDBYU5cKSHosdgYZXQdaXPV6hRUn4aEdc3lj69ua5aJ7aHz8vLzkLRknEswoxt0C7eJ6FNFr9ptSvabsIRZsApWVxMB78jbMjGRwBMnrJ6TMywGH4w9MgNPaCakkmV70OSUc6IPkTPqHjdNBIyHZnGASISqdFBZ/vgCDd76jiXmF0E8G5CvZxyFaeE04dBThx0HBDK9OMamZ8WcG01Uel22P7gT5IhJEhUGvXA6raC7hilz0mBPY9SY+YByT97C9+mMp3jaBe6QfNNjttsYKKQ90g0sSEvhkMSUwmUvFTb0DLZf5Jhnx32jAh5tTUlHsB0r0gXFr6oFj/C+xsSWUt4LkZIL+cNLtwdu4tOXMN/yQze6kSepTeoI9S7vOwunB6NAJWR5R6nyI9+sTSj1Krs/4sV9bmn5VmprOteCQ9JgG63GLuhjZ3T9trcT3LrUmMl/KC7xQtVklW3KpHIyAUbR6SVrir2QvYOo7pEV4RrCvc6r9m2ujwCTHgTw6jIS0SAT2xK694z//+NbMni0TESoD+nP5Ff063R5uxPWZcK2AfpG8NmfN9KQTmV/qmxlXhwaKB5SZmMf8F4cLeesegrcIAAAAASUVORK5CYII="},7688:function(e){"use strict";e.exports="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAQKADAAQAAAABAAAAQAAAAABlmWCKAAAL5klEQVR4AdVbeZQUxRn/qqt7ZnZml2U5FjfKsQQBWY41ERRwg4iBEMEH5CIaiT4SQUHRCDwIEk3y8rzgD+UwmgMFjRxCfMEYjFFRFIJRiQi8hMilyLUKLOwxM31Uqnq2Zrt7urt6pmfJS723W1VffUfVr+v46hgEFziQKVU91cpeq6V003BJwsr5Tz8GVNHtmFTVc0Ni12sPoK1w9kJWCV0oY+qNl34NKrqulFqaapAkZc0yALKhpFTHfYZslA/tWhjbePJglt6OiXYHQP1B/2tISWKdTIxKt3bYALAwSL0Hva2cP3lr7NkDFoQsDEVKthsA6oyhY4CQ57Ghd/WrqxcAXAZfevlOBdRbost3/IvTihkXHQD2xSFeul7UcNYIQgg0nq4HaD4nbJPUp3aH0nBsWrF7RNEAUG/uP4rEEuu9urq1hYZBAK78BhjTfwVnk2mIbF0HaO0jAPWfWtlc01L1wG1K/cFbijVHhAZAnVpdB6UV6zGQi1xrbCHqsgLo8msB3/agSVV1wwSAsyhvrAXppScBDu/lJM9Y6tHvDfnEf6aXbG445MkUoKBgANhypl3UczNOpwaJ7LCGSzfMBGn8rTZWJwC8UN63HfA62iP2bOckzxj3u2JNYvcbdxW6fBYEgDpj2OuSmhptXc7caujVcM7rBQAvx3vfAXn9o2IgYgkN9+j7WOmyt+Zy2aBxXgCo88c9hD4/Pp86ML5yoobzyokA4HwMCIUCQUQ9omPX5siAYTNL7l+7hsuKYt+GcGHt3rHjSUP9ixggwmlucdCGc9mgAHB+NjRkOjREQND54VikU+ex0YdfEU4mQgDU2Vfvk5rPX+bX3dmsjq67EaTvz+N1DRTnCwBXKr+7BfCqRQCnfFaNeJmBew/aULr0lalczi32BECdM+rnqLFhkYQQ/fDuga3jpOYqwPc84c4goBYKAFcbocMCbaarho8fgap6n5M7d5seX/rXF7icNc4BgNzcrzpd1nmbkm652MroTGtdu4NyzwqArpc4iwLnwwLADKGmBohsoBPl5qd87eLBdW8mDu+egjYcPW1ltAGQ/snY26Vzp5ZLgNp2K1ZummbjHM9ZDqj/UEdJ/tliAMCt4vpPQF5+l++KYfYGXR0bX7NvJ5fLAsDWdb1j5SFJkrI0zsRi1t1hjHicq68+B2n6h/a/b4qTaByUqXMhMnmWVZ2Z9gMgsnUtoN8vBqBf2AzVA4FMnAHpUd/L0WMlmHK/u89zWDAQyg5/2JP7DdnGpu4YvkdJJ2usynha69AZlAWrfLu7cWA3JJfMBNxwCiKJDlzUjNNN50D55SaQvjzYRvcCAB/aA/Lca2282QwFQpv1OOg09grmsFhFwaOepVuQB9dtTDz68rdZWbar42TTACczm93JlDtBWfqqb+PJySOQWjQZYqmmnMYznQwQ4090sgoYMF3uPAMD5/7JwEDyCiRRDqnZj4P2iz8CVHbPYdP2v38DJ5oAsO7vdG5Y4/FDm3PcVy5ojVMPT4dYWTkg7LlgAGnM46CnsbXbW41Y03RYyCvoeBcEvWYkpJe8ngtCslkh10BHJm4CoEajk526SIT6PAFmeH33NlDOnHSK5+SNU5/k0LwIUot4ewysJ1B/QBRYbwC6YjlDY6y0ltFMAFCiU9zJEDRPXqM7OLoyiALW0iKWbDk5+FE27ZfAh4Px+ekwATCUqOxkIl/q4yS55vPq2q4aQhD3vBNIGFX2yOFDXS6OMaIJgBSJeA/eHNHCCEQ0ri1qkY9nZ2EDGDjSlvXMdHMBoKzC3NdkeoDf7OWpNVOAe/QXcGSK5VjwUUZ8ZnirMeLyZa3lfmlUUmqO20wPwCjrD/gJuZWh2jo38gWhaT1d3ZZgtrGcaXswbm8uNOQa70JHCVsxRIE5MUGD4eMMCXXYACDu7q9QSSuDXmouqUJ29Jn4iF867O3gWA2gK8dbs/mnbQDkL26TkGpH2/JeGePYAa+iLB3XH82m/RLGsHAA0PMNc9ib48DPUJAy6Tt3B2EDcizAAW5Ah0kdGg4AYp7N870AYgf1IUK8DNiGSRTIicMiFkABnBs0eiqYHp5Qmw+DrhmsNNMDCAoHAFUkT6NHVIIgqUkBBzvgELvB6mj/LbHQiIXBBMAwTDAs5PyTbDXQo6Zz5SmMVLE7LDrwhJoRwDY5oQPJ9PrWtZBe0RQhSNf/2FcL2zOwrbNXCLIE6lPne4kXRM/sAei2vyBphxC7+dG2vgD49HFHSVuW7N1hZoyTnwKbh6S0mimsvASQ3ykv46L3idqAERn+Iv3PAKDrRQGA1Ume+yQYCycC8nAu1ZXzwNA1kCJRswlKw+lgTYl3gPSsZcF4g3Bp1kkQQq4CVoP0DIEMGWWl2NKRiq4Q61IFkQ6dzD9boU+GnQeGnvld9BdtFTB101Of5K8XgPbmRhdT4Uho3aMQfXqxeQweTlOrtK5alkFdCz8EaOOb5n0T8PYXgX3ldgn0EiRCzwODTJZC+zZHCEjoVSC94TGINp8FmR6Dt2ugW2XzIiSkEaKmdKYiMwS08D3AeP15wBF/PyBkndvE6S1Q6F6gpduGgGG4+AEtjW0GBSn9lWchmseBh0BdoGL87suB+BgT+ejtHF7S0qQxotkDiJY2u4OVC505Yc36p3e95l/eDqX4yN5wWlvOtwFAX3TlAJCPdnJkXz7sxeE9GOzcwMsYaTrXBgDRM+PBizkMnd0paj0uM2+YzJjdMXoF6uxEb1oAiUf+DLEZDwLQvGcIenDqqSBTkPEEBUyiYpSiuzyvW6Fv3QVK6+Mo5iobf1kFsMndo0s8QCfSwXWmORbTOzxonHW1u/mAB6fuwm1Ucw5QUil6iWYPSE3Rd3tH7USPnOTReNPXd7wMM0FwcTwRvcPjjedm2GUqfRfIswXF5mrxeW47SpON/2QKTQDQpuNHiMMVkOgTAX3hhMwXK8g0nX099lhudDom3a147Cncme1U9rgqMm8MwMlP7AXRuIZaX6WbALBSDSuH7FwUHQoCot1VXTQpcG+w6pDoeHeeBGvbXwJGzwn0NJiVWQOTNQJek1nl2FdnbrP8M3rl6Ww8ZcS9Bqzj/Nn7APOBRDl9IIHdT4jpGRrAdTe5PoQyptfSNyVZLLluM2ZvA2DkJJDrJoG27UWAd6irbHk/4HwsHZl0BygjJoBKwWAPLbIPJGxaM5nUxlM51Mg/tgBadqe3XHmX5g6nDl3Me0AWAKZJ+9Hl0+isvYrek7i3hvK4PZHRbvsqYLev2lo9QldZXUsBlqM5V+hOAFpFxBFdIVJrPs7yZZ7IzKFPZLzvC9FFvc7Jaurr8T/sf5cL2hoq/3bXajnd0keNxD7jDM4Ya/QAY+kM+7DA/osJu3lje4QQN3DOagDqnZkcs9195hW+jcdD6t4qaz5TbW08U2rrAVYr6uwR96OWlsV0QHhenLJhQQaOAELfA5nAWBUETBfcA+jZILnq+swrc5/bJPOrd6kK/kzOWe/UrOF7lVRygJNerHzBAIgqUFJqyPTnN4klW77rx2obAm6M0RU7avSyTuPpoZn4SNdNwf+AJnXveyw2aFitqPGsap5DwK3e2r3jlsPpE3d4rRRuMiJaMXsAqqhMKoNG3F6yaM3TIru8PC8AuJB696id0vmzw3wWC84qjIsCAO3uyrCxK+M/fYauf/mFggBgJsisMX3TEWOLcv5sdX4m7dxhAZCHT/hb/IujN6Jl2+rtmoPlCgaAqyf3TblB++L4M1hNduS0fOJCAcADR+6NdKuaFpm/6oN87Dl5QwPAFWoLJ04gZ+pXYy1VwWlB4nwBwAOu+lAp7zAt+sDG3UH0i3iKBgA3ROaMHqclm57Duiq+LqZCQQHA/Yd+oMSUaUF+BMHrEiQuOgDcqDbzK5OJgZ/ChtaF09xiEQC4T+1O2Wj5YeyJ9/7tJh+W1m4A8Iplfjobpz+dJZWcZo29AJB61bytNNX///501tpIlmY/niblnX6D08m+1uXTBkAsYf54Gu//+4Kwvwd02vfKt3sPcBpm2261qvdzUqrlSgmIzACQqmvqpdKOG+LvbVnEt6lOufbK/xf7Oz42iMSR9wAAAABJRU5ErkJggg=="},6960:function(e){"use strict";e.exports="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAIKADAAQAAAABAAAAIAAAAACPTkDJAAADyklEQVRYCbVXa0hTURz/nW0+Ssc0zdIQDR+RFoGGFFkolYkUZCJYIfSgiB4U1Kc+mN8qUnp8KAjC3g+KRZRlKZSlZUGZZaa23maumWXTzW262zkrL9vuPdPpdi6Xc87/8fv/7rn3f87/EvxrJPFwVgEBWQQiBPyX+aUjEOxDdvLsfavxIk4+txEWJelI1iUavMgvETmggiDUBvYackhSedZyoiQ3OXZ+FdsFYbuCKJDp1ygewOnyz1cIBEEebESVJkgtjn01IARKlRyYSqFCalQS0qJnIS2G3tGpiJgYjr01h6BtqZJzGbNMQkBJ38nt4grEhU2TgG6euxrXW+5CoJevmsIdKFgVLBuc2U0Pj0Vm3Fx3l3HNJQTMg2bYBTsXtHhOPlc3FoWEAE0NdPf3cLEWxmcgTiN9PVyHERQSAsz+46+vXDeWt/kpy7h6bxWyBF7r27k4A4MWPPvWxNV7q5Al8LSjURany2jA2qs78fjLc1n9WISSNGQgDZSA0dIHdVCoiPnu5yes1+6BwcT/PkRjLwayK2AdsqGy7b4LTPgEDfptZheZLyayBBjwuSatSzpG0p1wa0axL2K6YHAJ6Ho+4057rYvxhrRCpMfMdpGNd8IlwIDL6k/CbBsQYygVShzL24dp6imibLwDjwQ6jXoHCecgkSGTcKagHDEcEjMnJ2JTehGi1VHObtyxMiI3PpdWQ/N4Fq/0rUiOmI7EiDjRRBOsRl5SNhq/v0FXn0GUs5W5UHgUixMWgG3ZMyIT0E2zhj0IpzWPSIA5Pvj4BPNj0zBVPVnECQmcSHfEHATQE72pq4X2AajIL0OsJsZhw3ZMRnpVSi6WJmTCZDWj7ecH0f//oJnQevAwXYFd7hr3OdsTTq08iDlTZ7qrwDaob/Qp02nt4KktrliDjj9dTibCZY/fgJOlY2Nap92Nal2ds9gxZiszUnDLoBX6vm6J76gJME8TzYgdlSXY//A42JngTXutb4PNPihx8YoA82a10OnGa1hxfiNq3teBltcSUDnBi+/NcmJ4TWAY5UtvJ7bdKkHB5S248fYeBmyeV+RFpzyBUWXBcFC53kCLl2q6EmdfavH2hw69FiMILXdDaZawzGDtz4ARBx6dgGXI6g7RLHsauluNZm6iB1WVrtZxD9urA0MQGhTi+ID7rKZhsUuvIgIscPyguch9MjFa+8FuXqP/JEMKWgPW8wz8LbcLaGDPTpKPZF+hfaG/Azrj0+ypE5QdS/4tfikUyWFZhTSjsunrGNWvmjOYN2MBxEaT+anut+EcSt9Y/wKYPTFLjUA+DAAAAABJRU5ErkJggg=="},1672:function(e){"use strict";e.exports="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAQKADAAQAAAABAAAAQAAAAABlmWCKAAAHYklEQVR4AeVbeVBVVRj/7n1sIqsICIKhIAIKkjCJmgJlKiYuTU4wWZqWMzWauYzmMsVUmk0Gf5SmGU1qizMq2mSbo40RmMjmioiC+JQdHijw4PGW2/kecxF9PO7yFq68M3Pn3nfOd77z/X733HPO953zKDCSgr+YEUjTtJeR4icqW6vTKCvO55TDEdA+bjj1SMbKGPuQcLfVNMWsAqBGP1L2pP9gQKGj4AAoNZ/e2vJvAwunh4CQHdO9KWe7X0nGZLZwcN6ZWo0OkivWnS1AfLQe5GKQUc6yrMEPHtFSI2QU9du4L6f54y89AcHT4pdTQD2LGbaQKAp8GK39Z4hV/wmEZiTkA0XF2gL4hxgZdVcL+FBBaQlO9u5UO2Gl+3N4KDH4nyiYSctcdd42CZ68XtL9XWgtTcsG/6s2jtCs3Z4MpDDaMxBGuo0w3qLESuxMscfJzhEifcfBJL8JEOM/AaL9xoO7kyvoGB2k52bC/sKfTVFvlbqCCPAa4kGARsIkAhavCO+xYC8zVEFTNLw7ZRlklfwBTR0tVgEithFD641oWhmbCmunrgAExyc5yOwhJXI+7L5wkI/4gMnwQuPqMBTWTFnOGzyLJiUqGexp3hyz1ax650WAm6ML2ImYLHyGesHskBlWBSS0MV4EqLRdQvX2yL8W/VLPsxQfeBHQ3qUUbXu0X4R+phCtwMIVeRHQoVGBSmNCL5i4yMIwxKvnRQCqr2vriSEIbi0pNBFwCpVi4k1A1YM60fazU6JoBRasyJuAima5SWbglCjjuYYwqSGBlXkTUNZ4W6DqR8VxSkQ/QWqJNwFX68tMsr2urRHk96tN0mGJyrwJuN5wE9q7OkTZIG+phjeOb4AurVpUfUtW4k2Alnh4hdWXBdtyTl4ELx9+G8oVcsF1rVGBNwFoTHZlviCbDhYfgzdPbIT7qlZB9awpLIiA0+U5wDAMp33Y1bee3gXbs3cD9hwpJ0EE1LTVQ3HNNU48W09/Dkev/c4pJwUBQQSgwcdL/uK0OyEojlNGKgKCCThZ9je0qdr7tT8pNAHCvUP6lZFKoWAClOoOOMLRvTFqtC1+tVQw9muHYAJQ24Hio5xzeuzISFg8fm6/jUuhUBQBNcQz5DPIvT/jHQh085MCTqM2iCIAte3JO8S5MnRxcIaMuR8AeoNSTaIJaFAq4OsLhzhx4b7Bx8+v45QbKAHRBKDB35Ox4FZTJaftC8Nnw+rJSznlBkLAJALUOg1sIYsejc7g6I0BllVxS+GtmFSDfL4ZjjIHvqKC5GQec4I8yImJ9wTV6iWMbi4GOp4JiO6V2/fj1FEx+m2z/Cr+TpWzvRPsSf4Eds7aBElj48neBAW3FHcAyTc1EVWHTSYAjSiovgKxZMsswJ17xI8LfBowOJJzJ19PBheI9KRt8NyYqXqxYc4eEB80GZZELYThzsMA3WxTHC2zEcAAA/9U5pE3lAC4icKVJviGAhKRI88nM4nxkDuOG6lRCwzUOdg5kI3YCHh14kKI8g2Dls4HooItZiMALewkofNceQHMD5sJjsRAruTn6gOLImZDLVlTlDUZhttmBU+HDxPXkJM7+lM8farDsiDPAFgQ9gK8SCLPKCrk8yDy5vkEWOsUHfehqPoqzCXG9LVrzMqxd9xex62zKDJVXqkrJW+yO24wbvgY2Ldgh6D1g+cQ957PQ0sGZT5eq9kJQGDVrd0u8xwyYPEhAevgW3wlMhl8hw4HXF98Ne8j8HL2xCLBCT+PaU/Fkk/yPNS3N/VbHwkwaRo0pj3v3kVY+ctmaFW1GRMxyMfVYmrUfMhK3QsBZjhhMsLF26CNvjIsQgA2dKHqEiw5uhZqSI8YiHSp9jqvZi1GALZe2liuD4gWVl3hZYy5hKoe1HJ2f7YtixKAjTQqm+H1rHWwv+Awr3mfNcyUe1E1d9iO1W9xArAhXCrvyv0Glh5bD3etsDlSSBZmfJNVCGCNwXFh3g8rYF/+T9BlwnY7q8/YvajmqrEig3yrEoCt44Ip/dy3kHRoGZy8ccbsn0UriVfe5OGhskxYnQC24XtkoFr/53bSI5bDieunOENsbD2u+8XaEkGkDhgBLBDcMtt0aickfpcCGecyobL5Hlsk6o4rUSFJMmfYcLbYm/+j/sIDmLhERs8vzDu4X3/gcbBCBkCsKxkCegMpITvReGX8lwm4xsejuBhaCyU+QrDnKPB38+3TTzh/txgKBMQaJEtAbzKaiYN1piJXf7H5eCh7GCEGyXEl7jcexsSjfJdrS4ljzr13yep5IgjobSz7jCDxDLI5ziHTtIr8h8qGE63rtKsnO942SQI51q+kK9POdgLFXLK9TsCoVR3aAnYdsM/WCCBD5TH55pxmPQE3WyCTZOTZDAn4N1qtbiPi7e4BaWc1jFKTTEgoGuwkkBmkQc1oksrXZ99FrD3/GFOckSvd4oIOyhwZJVl6hZMy10FGRhsZ7DPVakip3JB9g8VmLOZMBacnBNO0zp+hZcZkWB2Sv2tVmubb7YpSSLtmcOT9f3LyV1v6G8m6AAAAAElFTkSuQmCC"},1923:function(e){"use strict";e.exports="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAQKADAAQAAAABAAAAQAAAAABlmWCKAAAJsUlEQVR4AeVbC3ATxxn+93SS/JAtY8DYGDuAbd4QQoEkTRlCmzakEyYhAxRCYAjT6QBJWxIIr5Kp2yktj5KQJiSUPGoKmNSTQEmaZ6e0CQwpBUJJKClYro2NH2DLtmTJ1kl3u/1XVKqEJetOPoFtdjRze//++z++2+e/KwKJToyR775emS8BGU3AMJgwmssI5DEGOW6JWRrbFQUIOAXGGhjAZUJYvcxIreD1fFWxcdxlAILkxCWSCNH3/bbCKpqMIwhlj/ooXUaIkBRJj0ui0NSuRCry0ygDD2ZeAgXeJBIrtxUXOaMyx1mgKwAryq5aqpwd+3wAD6mxJxYAnWQo5O3yWroQXiySOpXFSdAFgMWlVyY0tLlKqcEwggAxqrVFMwB+wcwHlH3FDGSBbXXRebW6ovF1C4AFpXWjmju8zykMZqLjmmXFB8A1VxgQCgzeYwp7umJ9oS2ag7Homo3mAsvKmGGPs2q1F0gxDlIR+3csxby8OwAE5ONg2g7ANtrWFD0foGl5agZg4b7LQ5ol5YjMoEiLoki8egAQlEvhgtckzrj01ND6IE1FRlDBE2SZu79+6lWPUqOH80GhemUEGGmS5bqhWy9O1CJSNQCz99QubW2XPtUi/GbwisRwvHBb+WNqdasCYFZJ9WqXT34FxzmzWsE3i48AS8Z+/VrBVtsP1dgQEwD+5SWZbUJhJjUCewYPMQsEthVuLp8Xy54uB8H5B2rutLuUTxL15XUdBCN6ynxeGe68tL7oTMRiJEZtAY//sTbP7qZ/T5Tz0QzSl06MJpGdGrq1Mjua3IgA/JUxscEu/yVapd5FFwQRlHej2RwRgB046PXIqS6aFzHouEadXLi54ulIbJ3GgMfL6sdcdkqnu7PCi6QoEi3xY0CYVieVYFzFxsKaUGqnFnClTdp+I5wPNeIG5dOFJPby9brCAHji7bpJXgb3X8/UV94pJQ8UbLflhfoTBoCtqWNvPLu6UIE9OY9rAwPI8FGojUEA9n/R2k8xGLq9wQkV3hPzGHIryCwuTw/YJgYyb55y7NESzOD15o5LhUGWoIiAqOue0UN6Pox5dWCf60666lJg10n1kTJCiCkjhf2yGeBJrtc/Cyw51JJRa3e2aDUkK9UAC263wN15SXGEQwADOwzwF3c6fskDO084oLJF1iiD0Va31dpYnOXyd4F2t3OsRgkwor8RUowEXjjugJ8daYb6Nhmd6YY3Kg3gOriudR/ZYfWHdj+AE7K1blOIkJHa6vfZD4DChPkq9QfZ+JffMrM//GBKGtjsPlj5nh3+8KUbfBgfS1SSUfZb59wwp/QKfFbtgeVT06H0e4Ng5det2lUy8du8ksCXvQ6P8n3tEq7V+ObwFHjloYFwV54ZDp13w7LDjXDyMo9m65v+WS/B7P0N8Dy2uCm5Zji4MBsem2jxK+m0mlOhmhK6nLOJew9W5+PAEHdcj4dC08wCPHVPBlxo9MKrJ9tg+zEHjMnqgGVT0yAr5iDZtbUtHQps/qQVjuMXH4hjzm8eHACTBptA0B6DDVOETX/woG22LNHuZqP+NxaGMcTzMnKgCX51fyZ8eLEdDmJr+DF2iwdHpsDDY1Ih1RSccVWJ9uBmpOxLF5R87sR+TmDxHWn+L55s1CanK2WpVBkvMhDyMaraFZ+mMqOBwKzRqTBtaBLs+ocT/nShHY5WdcDSyenwtcFmMOBqpKuEMyN8XuuBX2MrqnbIcEeOCTZMz4Bcq7GranGVEcEwXBQFyI2rdoxKGckGWDe9H5Q3eWEH9lveLQoyRVgzLQOsSQJOm52BcHgobPpbMxy7JEG/ZAG2zcyEe25LjqEp/mI8ussVgcKQ+EXErlk0wAQvYL/9AFvCvrMuWPFOE3yrIBmWTEoLrh34Vy892wavnXKCF48K5+ECa8VdVjBha0pkwo+QI8oUokZL9FIuYrPn3WIqLph+f6YNPrZ1wOk6CeaPt0CySGDL0RaocSgwfpDJ30KGZxqD4OhlQyQ5uAzLFnE1FlwXR2LSkzbIYoBV37DC6VoJgXCh461gdyuQjl1i470Z8J3CFBAT/NVD/cGlvxUX8nxUpaH0hOb59DVlSBJMzDHDHhzh69sU+NHd6WAxGxKqN5JwbAEUx0DWFqkw0TQ+W/CZ4QasnqO7QkijIAjQEJ2jj5fwmyiCQQiLkfVxl8PdI3BFkH20Npx667zhGNAsEAOpvnVcDvcUL1lUCv1TTf8OJ986b5LPe0ZY9EgWbwG6XTrqLfDh7FNdu2G0XZhBiJxmJm/0FsP1s5OVcFn+vWWyybBfP8G9RBKDD4IAMFnWfN3Mi/v1npLafdpswXWvYrZYz3H7g9utWW/UvO+h9AG1TvEt7dxxFty2chFBMWqr+/l4jE/C3Vi8ibvd3E5hN+4iWzrUy2GUPGdbW7CK6w1azg9GSk44riIlVqA/Xns71bvBh6N+/Qiax+GWBjYWj3Vxgn8M4JmFEzJaQKAXeb4vJ6KwswHnuZ9BAPjLMGvyUoy7a+tQvGJvSdjjfB7vw6HmhgGwe072CVEkfw5l6Et5jH0crioeG7b5CwOAO5trNePgwPQP7N90JFkzUa6dB4aa0gmA1x/JPpdigl+EMvWFvEKFZ20bihqv96UTAJxhZd5tWzBecel65t76jk3/yH/WFnS6HcL9iQjAjBlEzk4x3dtbHQ63m3ncMswPp/3/LSIAvLhkQU7VgBTjNMz23o0SAy9TYHJDhKYfgCAqAJzhwKODj1lEtgpXS95Ahd7yxLm8gxE2z7au6F9d2dwlALzioSVDd+LF25/jzIB/Beodye88oyttzxQdjmVxTAC4gHeX5m9KFcmTeISo9SpGLP2JKPcSmS6qWDNitxrhwb2AGuY5e6unOST2qRpeNTz67wUo3o0Wp1Q+M/wLNfo5j6oWEBD21qL8oxkmNhzP1MoDtJ7yxADnZ7JRzNfiPLddUwsIOMv/NFXirnrWR4U12C3iPr7VowWg406gwk9xe7sjYJ+WZ1wABBTM3Vc/ptUj7cTT3el45KVZVrcAYIyHZN6XmLK8Zu2ouoBNWp+ajY6kYHFpzYS6dvkdwoRcLfGEuABgzIsb1osyNc6qWj+sKpI9Wmi6AOBXiPdYFhyozGqVxF0Y6QnbckYzSAsAlBEFzzFfbmmSf9K0dZRu55n6ARDi5dyymkxnm3I7Hj/PphSW4hWf1JDiYDYWADx0zYC+imv5j10W+XzjE9eiOEEBOmQSAkCYXdgy7vtd9TCBkgkKY/kKIwPxH+U5isKyPApLc3soRgZxqwqkgRFSiyfWjVilEiM35yLt3sJk6/DyX5qvt56zCsMvAAAAAElFTkSuQmCC"},7038:function(e){"use strict";e.exports="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAA8FBMVEUAAADHFsHHFsHHFsHHFsHHFsHHFsHGFsLHFsHHFsHuuu3////HDMHinODXc9PJHMPJHsPHE8Hut+zuue3+/P778/vrr+rnpuXOScjMQ8fstOvjmeDgpN3diNrck9jaftfRXczPU8rKMMTrx+npqufmouTYdtTUbtDTZc7SYM346vfx1+/nuuThld7cg9jWftLQWcvJK8TJJsPIIsLHD8HHBcH99/389fv57vn25PXz3vLu0O3tzuvov+bks+LendvZe9XUdNDMP8bKNcXy2/Hu1u3v0u3lteLjsOHejdvYidTXg9PLOsXiq9/hqN7gkd0zo4LZAAAACXRSTlMAsajs60tKB6cVFYoAAAACW0lEQVRYw+2XWXPaMBCA7YSErA024rS5be5wX4GQcJW0SZO0/f//ppKMJw4xtmS/9KHfEzOwn7Sr3WFWwFyJlxCAS/FKIEQvIDAXUSzA8SEM+P4QimtBhFCIgl/91NZLFc4TEcCDebX4kJFlDTw4K4hp5dpSJixj/ILJsHeflo/0gE8wb7107+QPMjqHYD7aPmbkT6TfgFGA3su1W/mUzBuwCVB5lZa/cPv8DdgEk8evZ/8okgZgFKxPEn/a7KcIgFnQcV7/fv1q0mAOwcYOXta2Gg3mFNAKLLq/O3BkavAJvqdXz8OEfbSBJ6DLJ2iZYDHTj83Q4xNQkOmYgD23QP/lnIAn4BWUF7KDuzavoCw7WQyBU3D4NIIPI+AVFJ0TYCDgFtSsCVht9irY8DUSntz16/sMbLhT2BpzCIYANv+SAMV8mXkIpoN6SvIj2WijM4JpQ2IiVTkjGEiMJDVXAarj73Ij1ZNEM49/VXIVxGj+qb7H/wHq5CRCwV1gX3AwAXe0wrHG8bOCKq1jVgEXzFKS3PBPxUuQACVLFLnq6VyS5DENAxRvAYytgwo6OGnX6dVaAH4CjF6gpSiZH8nHJUweF8dfQKnm6HlNFQiHn0n7eVgFoDatUnRw8pU8/ThCwCqgmPRYKa5YySs4nE9gJ26VYwzAL6ClJ5AHCSYAdZfHdUAQTEA5kJcPLKD8F/AIZrj1dPCnIkl9VwE0cMc3FT/IaOzcBe2UxEZ27C5AlSRbvAEUl6VLKxXifvR3Y6BEQq99oRfPkKvvDVm+b0LERwXCtRiBAETEaxz8F/cVtnqf0nH2AAAAAElFTkSuQmCC"},8537:function(e){"use strict";e.exports="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAQKADAAQAAAABAAAAQAAAAABlmWCKAAAYqUlEQVR4AdWbebRX1XXH972/4c3M8yhEBHFA1EStiVPVamNjVwx2pUo0alNd1tW0GleaFdeya9maoWSZJqtatSbGrhjbSiLVVAFRQYx1QEUFFQGLDA9BeMCDN/9+/X72Pee+32PQP1JTPbzf75yzz573Pvuce98jMbVqtZqMW3LPn1crfddVzGYmlgAz/iVJNgZGi/Ns4t+O6zTgB7xsJaxHOCyq/FQtTVKnq8XLSYVzQMvED6CBBy3XFQYBDzn7N+Tqp1XC77adPd/ddvG17Y4+euFd94nw0pyRjI4GOaPIVBwdLufQcmewfhCBjuSIYeQ4fA1g6LQ5L6264wNO7Thw6V93uRk/6GnY4LxQyOVlVDn/QJNY+kylrfsPCqMW33WpqG7O0DKjfFxDfDAlIn7sHQfHRUUkHWd5U+djnwaYFqDxKALK7HDf9OMGuoyL44dh7vyYBcAjvxjI2jWnC3KCaRPThmJjmlTtaldai96zGo3v19XpD/aF0NhygwVwj7MGX/1DKaYD8OWsA+CwC4pGvZwm8ImyMtaBHiDrkZ+mGB/pnB848FaLelaqlauKQjymr9LXr1iNwq54pMpo82+Ysx6Z5bjBAE9FrUJelZcZMgavrtJrZ294w2a832r11mfrBo2wxROn27b6JlcvCnHnBH0ijD4Gil5GOM9cXpAT4bV0A8bwrSbNyciF/4zKOdNomHtPcDwJM/do2Ps5I4SpReFZBFRG2QbOla5mKwj3tK1r7ZalC2xM1+6MtkfrxcQ606LNO+Fsu3fGSQ6PX5E+NxbetMDfxwE0IAgsCO6wqHeY19qTjFp0Z84qGuLcgyCH1RgUBQLPZATpPuv/csVr6Ipy4tdfWmJfe215hpQqfXsUvbIqeUXY+ihVbNnkaXbDKRdam2dDdGAmaX+euTRUcH3EM3gmZkmOEwYeJHBQH4eM8gwIRjijgSSjy/U2KSjDSnQInq2IS6o+c4WvZh53Fv3QopS7YcViO3r75mxFxhJ1+QQd+ulxQiGx1qZBduuJ59mOugbH7/+qxa4dg7H/3Kytt8fe7tiT1ZkDl6MD7qxmqRsUFiLGccJ+c/LR9qejp/TL/wSOnt71nv3VmhdsX19vpv1+jvCbhKczCzT5gfmfjDrsE2885nx28Cj7u6nHMcwa9mEkgdYWza5SLIUEiHvo4lGTA8VH2xGZ1u6Oj1TIucPGWUuh6DJq6whjQbEcd6hzx2SDxkAQNdvUtc/OW7nEp41pwS4dPdWumzA9Ln9gv7On217f1+bRqEVcsrPVvrF2hXWrGExvHGQ/PPzEXAbjs4aOsZ293XbaSwud7JYps+zb61+pZWGfbhlu41QrHtq+0eHw+f7U421KQ/MAvJZi2fbI2UTdTwaM1U+ahPs02DH6uORQ7YsjJtrslmF255Y1tkYFhra9p6t/jwVCYLtVhGhL2lrtni1rw0p/96NNb9qU+ma7/YjP2OVjpuYLQ6Ts63t3+Xxl+848egBwAjrQrp94pF0x9lM+hubGiTNtfUe7wXf/RlhjkGvX0uw4y7wRPYOXDtWOl/FXjj3clxH212+/aGe+vMg+pygt3LHF4de+9ZzDiNxD29+1ee+usuf3vG/HPP/wALak/3hFj316wfAJ+drhDS22cu9On69sb7PZzcPytQtlPDrQzhk6Ns8qsnKunDireaht6Nqb48eBBzdENgaatawIauCpQXpg/AekACm5XJWVtkppvWjnFk/dc4aNtZvfecU2dO61pVq/cdJMW3DMGXae9h9RPrZpiD167FlOF79OleFL2rbabRtXWy9nYmizmocoA9p8Rn+sjPqw1qfC/ca+Xbaus93Gl/c/PrMLXc4j2idTOcazPSEGng2eDBEjJ8kH895dbf+idL5g+HjrqmRKs1dP0XWWPdYmB40u1TvO1u5Oq1Nk4md8XWPOh8ENSuHPiw/8bn5nZb52bNNQ58UWIxOI6oe1rT2dNuf1Zdata/3Xxk07AD3L9AxMBngWyEzfAj4h6/l4FwbZdMD3ldpz848+3W6dOtvw+sHaXdNPthHFOvuzN5+1V7SHD9UotN8RH5xAEdsn5WktxZKxDR5+f5M7guz5sDa8VGf3zDjFFs862446CH5uoxhlZTCzURfS7B9pj5d8Cxzafk/naVKORsWlcUJs6uqwgnhN1K1xYn2j3TH9JD3mVG2Vilk5TWVcuIg4RfZFzSD1h6qA7d8wev62De6I/U+k/XGZ16mYcyIcChcrc/sCA2z1wxHvgEDzVPkABwRa787X/r63dZ1Sb6lOgT67fOxUPw3mvLbUo4hDODGoG7dvfsvOULF88rhzchbXr30xH1MrKGSxse/nq4CeNWR0BP3WvTvBkz+z1+0etTA8DNUYDeJjs35fFbp/z3YpPVeqIFHQRijdYuOoW75rmw0tle1k1QEi+uzu7fa+jsETFRF4AFuyc6tqQWqn1xhEwWSPtxRKdurgkb6lkDG9IcusNzt22zgVNHhwikTZHLHrVezIEuoLp9Gevp4PLJbnvrzYNup0IOoEOT7dDngaZBt4kzMWai/VOiAa/Entz31lsW3q3JeZx0mn5o7AaE97B4Wv6Iha2Cd9jE2ym7SvtbfQ/JUv3IxtXvx8oAtG65v2xxNmWqHmMZildM2zVnz0NqvMPF2TopV/cq31zTrPSgu+Y9URk8yUrqX7v2mmFK7WXGxK/36TFZ970JLd71nlsNlWWP5zKz1+h6UbX7PKlOMtfesZK/36B5bs3GTpG0ut+PR9Vnj514i00qM/tGrjEOdffGSeJVvfturkWVZY9jMrCLdy+ElWeOkRKy79qfQ6Q3T/ZUn7jgHy4bP7mfm2QveLarj5+v5XJuTHIF4pV3rs268+Zrf/5n5/bQVhbSu88Es3EkfQ0ndWWPGJu606ZKwUnOwOwgmOV0OYbnzdei78G4ejbGHVEuue+wOr6qgsLrvPis/+m/Wedrn1nfAF6z3/6+I3xvqO+0Prm/15S3a8a4XXFpnp0lV462lLt/+PXqD0CbbY0s2rHZ60bbG0dY0VXlxgjJP292ukZ8OrX3rS7njifhuu2kGwvegrK/wmGKvj8R0b7Yo9emPTX4z7GUkBBFYmyfsSHhvG9k39tE8LKx+zyrgjLX1vnVln9pwQ8UoPfMuqY47waWXC0WYynmwgK3rPvsaKC3/kBkT8vFemJRj/+hPWN0OZp5au+Y1Z42CrDpvocGC9n/mSFZ/5ueS2Mz2gJXrR8jl7y87sWuPbwBG0Jfwm6OnABgEwpGKFSb1W2PjUACaF1Us9yiiTbtATWXdWULq/8o9WXnCrG0xKJ4ITQRSubT1f/q51X/IPctAMRXJ5tp1e+JXhjERR7T3tq5bWOLaWtnLY8doWP7PKtJMdTAA863QiFVY+mqFq3PvZuQdkH4vp9hXWNG6b1Y/ROyzeRmFoaIWmuX90cwRM6G6zL7W9ZIkyoNSqdNuywvrGnKBbxiDfn33HXWCVo86yassIwfS4qb1eOeYcq6r3/T3lROs7aY5Vxh9lpiOnOmpKlGOViYIp6qYHm+r4mb59yJwKaS4HkNq9p1+p9ezay5YyHaM0l9Ey0qqqS1UZajo2e8+8yipH/J6ZjtGqnFgdOs7rgel2SZY6bc8+Kz/3fat78hZL63rcrseajrRV9dqy+ocb9E6w/5XYyXvX2S823COJWuBNQacwyo3WfcI11nPUJXKl35vQ6WPfCu8+ZXXLZHjHVplKkdeX1L9+1EX2H0Nnu/44IXsajHd6sLixiqLanTnB+vZZ3XPzrOHhyy3d9bYTfpy/kq6dVr/sRmtYdJ2l3VszVRXQquyq8nqC31HQZCqZn8bjwIFaS3QtJ/qeASIkGyiKhe0rrfHBOUqpfxIML338WnHtw9b4wIVWXKu6QMQJLwWdT0kftWr2vKVBNveHodqLAY/lFaU+HtPTjO+bapfc1E1a9Fn55Tus8aGLVOn7H18zVv9/38nuTdbw+F9Y/ZJv6Yq7KwuajGcLeybjCKKvnsDS/Cj0e0B0BR7DRlJfHktUr8gGYElZyVISAt6TJwtt663xkcus7tm/F+PsNNDK77wRuNLq+63pwYus8M5S6Sh1O6Uwenq6S3dgCqrbgoYak/XQVrXgGeCaiy6rCOpxRJdDHYZTfM/UyxFyjmeHLiOlV39hTb/8oo7M5QH5d9elu9Zb0yNzrf4ZHcEVBQH9CRwvgwicmuuKMxQ7rwFyDobzIJQ11YD8CiwInkrrhR8YwJNGNjiTPjHAGUzZV+KTtm+2xkXXWP3TN1nSceiXH070f/Gl+lN+7U5r/NUcK+xYKYPQT4GRjujmwWH7YgMOUQZ4RsgJ4OnbneB2a+pFUNBsT8ggNxDL2S8sMCad5BwHAIc5gmM2SGBp3UPWNF8FaN1CLX40Ld2mQrzgy9p6P7akImvRiY9+wYqOHhQijn4ECqM52Wp0F9RbrHv8Et0R+Y2pj3ECTCAiyniB1wLAwNWH48QdFZ1BYWHL6JbY8PgNXpCSveEIEvi3br1dVvfiPGt67DLVH73yRid0kU6+x1Wka2F+lGOOdKpQvDnVpCtO4Upcm/VawiL2gnzhv6EVIsarwcBTiAsRzkBOdBBGkxkwRiGEQKe+uHmp14auE//SemZcLODAVmhfZ42bfmKlPS9a0tlpvaNn2r7Rc61n0EkDETUrtD5v9ctvslTvB41CjLoyOGlAqMbooNQWuD/V+cVrr3DIBDmpGnUONmgj+z+5wtWHNDSB2DMYF5oXQxjgSeSzv2SoO0JDPyJRwreDcMgUPJ3usfr/vsUaFl6hC9R6AbNWbltmQ1ZfbXV7nrK0b48i0mOlHa/Y4De/YQ0b741oyqjdVv/czdb4xFWW7t5spgJMw9CkRWOmdDLSo0og+KhhHja47gRGMN8eLIYgY3xAYxm4flePocE4o/Cp+XVYvR+DpHl0TkZmCYrhgJBeUTGHySnFrS9Y8T/nWNcJ11kycqw1r79VD0zyIhEsSKAildEk1rTpbkvluK7e6bp9fk+GaxthFDLdcqEiV/KqKsikMkXQivoi+3ycrfsYEDoTHAXQddW5V9vcHPcYUK25EyggpAvOII2IOorIKU6uL+qE3xYxHGepJ+3Q0C8bKAQyfdptjet/bMW9OqOUnpkVglO8dMfQK2PnDW7DxgesbleP9fD6Cr6eUVgmPHQKunhANDX2f7dkNskZflkTDJmoInHVDhmOzIrHHApnxcyPRIzPl4SHHDdEgvIqDzxsDTzuRZK9RY3QsekCSTUuTDgKpdGZD1kwusGKI4SIwV3SToXIM4R1RdKdQmSgq0tNf71lpUn6eyEMQXkaocJ4ejKONfBxuHSr7hMf5jiJj6YefeHFo5tbD/b5mgwhg/KLEE7QHw05ckp6Brk4IU9zFBBj0WWZgbFEHs/HrIEupq3GhZF6QzRcoSwJiDH8SUxMexRFafYlPDAOwxrkhJKcMDH8hhc6LefryACPoIgd29YbzoQfjfuM8LKzXz28xYQA+SkASznBX4hEY+PZ6AwjIwQzFiFCPe2luNcKDHCYuKEMuCgDXFEqTWyy4lhpAhyjab1CAMc3r3q2AA0noIj+bsgzRfLSZr13PKxFEdYEGlD5KLVdH+nlAQoXIQ8UQaJpjUz1oi1yz1xlrMM0wVb++T2A6NPcM0EPvO1HjOYg8sMFwxlSWIgYjX2KwUxRknFfYqXDmiwdLALwiAxrOJH0JRpsA1KS/U+EUcErvQbM+XBmKyvJhKRJjAkEBtZuBYGrnXrTAwweBAIdaJLnkccR/DUaa+DQkR5qfhP0yDOHECURFBUWEYXECaORwQCvBcBIf2g8VaXw9GZLWzznxEcIpL3/raCEwB8anCLFnSbWAWoEoUI2H5rYkMalsbqN1UtB0WOMX8bCkeY8gOEE9ECfWCewSx8M9syOfCWGwGc1ACQ1L34gaDFXFEZEC+Zi7B7V2HtwgeM47BW30hEtev2kiYqZG0OUPf+0jsLwohHRRuFgPPLYIn5X15htARr40JMJMr48ocmSQeItuSxz/nuWikfSCJ6ANJyssZ9O8AaZOTo6ISJ17MspoPp+QIk8ExAAMsoJI79EQAwFRyMMawUqymWMx0AUd0FxrB5DgJElOK5doWJ7EHVo+BA9GpnBrQ8adACOPMkuyQmFMVIg6OE6EF0egwkWcJGBT/XHSQ7Tsp8KZKJ+QMLe/O8DHMS+wCh1pBPH2oAm5vEIxIjAxxKK1ae0T1GUyKMECtHocAiG0LpFyHqtQxDDB2fE9w4dwotHZtSjRb9ulQMprkmD9qbkuZ44R3Cv+CJzmWwDsavwMsfvAuAIxLpk+SOx93gCTBRAMTH16ENPeqM3hrEW58CYQxbO7ES/+PTUBZd1DKEhkNRmCpyIkAXREayR/uCxRs86jQ7jcQZw8HCSfspHKBNG1GVZiC4YR0aRnTQyOOoIDy3xAOn3FFiEbalLpPaP/jkAIQjlo7HvIQ25DrtTWBdTEoVngLS57IrkqYoCZJAzZyxEFOG2BhEGeITV66z3LQCMMUaTJeocx0+PQIshwJHPSUHfXskuV5LR+54URF8Zj2h3NHoim62wV1bqJpi12IMWjkGY4wRXMqYVR4aa3/YYezFUj4F0Y+oz4xFIVFCqtvAhB+PgS49mRAJcMomG4SE6bjxOgAQctghFEuPhrak7FGeC0yxFZGBxdL3fNKH3gggu62QitnBk4wxurFrgGcJ5aZYXQQjwhh9VeA0GGAozGsKDN12PkfVWGq9jCcMAoDA9yhJh6Ik4Yz4Y5hkgOGNSGlp64LE+YBxZox/fIhRDeMXTwreNFpHDB4cLpaitUJqmGuR0gocg+W+BpDf7PtY0L5rwpKmHjTc/J6MiYkQFdSIwYKyocd8ujNG9Xl7PoqoFoulpKW44AiOgiakOT3BwoGeE+sHSkLuBlhwPo6FFcZwCbb3WgTOmoILLR1MPDM7xTNFcTi20lKw0VVdnjkOatgMPTGRF9jAkmEiyTHcM//J3ghifzcKCZHNrwlvs9Zj+5Wm62g7T1Q/FaBSwmDFcVwFLiPcoCx4pjuY4AXzgKE7PFnDDBSczwMEJXks0x3gcAgwdnZfGnA6ssU3gEy5UqR6vOSZdAbastkBeu8QDR4Be2/zX4/F1WHQEstg7FY4Pr+A6eiar6nK11Zofa3BBEQymoQQG4xAMYM8TfRyIofrJpWMI2cC6fvIeQ5nTYzg8kQeMngYd2QEtxyvZh47oInhBN9Dy4doO4FC7hML+dzauVwaDFQ215Fwlhj7CzaIuXjT3mLxM5AtNsgxs1vAQShI1iIAREZSKFZ20xSGs4wQUJ2LQoAgNftBhBLQ0YJo6DFycRZYAA4WeT3y63CvhyOEDrXBS3RbL2g5JXSG//mY1gPUgR0MaJE7kRVAezfaMZMh7qYypmzlIr8plPHuWFjo3GqUxgEY0MGyP8g7FASOLR2vmKBgvRKyFzPLIka65oVrEwSEIXs2jDOcT+OKUmHU8UHlGaA39tJaoQJbGk7VFt5mt4O8F0EMtZns0x5X1JUXWjxPdGEpT9ESHIii+jzNFY3UuDEYoxhppj8UYQWWOEUZJncEewX5JmXOi0sAxBN6MySx40qCPmcaYTCoKiXWyJjqEngA5baATSqptwENUYXApCzy2hULs9x6hItK94R7hmiRdePSsm657fVkU4u2CSDmIMRpDgWMoMCLoFoTOFRdCs2hQFMXAc2dqDA+XrLErrzk0A04GrbGdBPYjERr44Cy2UuwpnOgT+aMTPPXjmcAW1qN5YZBSWktxu/u6UGC1G2/4R54tDCta3Qy9hIABAv2sFSWGgI1CRCLe05mDi4NIQ4oPxvHQAT4KYRyZgwPgCb1+fA1liSgZxTkPH9bAxyh6cOhp0LNOJpB5sXagH3UH2fCiNoAXnFgeq+N7WNlPBY8+a2q8T31V/alMtje22PwmvZvvUVGMUXTF5SC9eHSFhJfIMP8dAkQ0LeVHWIfGikgi5f2NMp7kJoJhKOcRUk9EJTyRM+LLVOpC0i6geod5JLWfeVWnf4mus1UZze8feCfgMqn0veimvk4wjMdxwGl6OeMPgLy4mWT2Tkf2Vye+pgt1MmLxnZforci/urcClM4Fek8g0Vyw/SooOKz5K/WQU6SYH6vCl+iMDuUZM5Vu3sI4k7MfHggRN/TwBdcbXQ19BuyXdzAdHN/Jwn+2zPjd5pJHLbzrp3pBcBlKukIsylgYZTKjxMwxucCA579VUpQzLGeZK1iraHQIsP2d6QbWyoSNGOYO0jzql+kUtRA86BEhBCAGzWGBVxwH2U/rb/vP99BuPeeqrxYLyTVpmq5yISjimgeDcQRM1GDMWnROFO7GBzyPFACaesfNZgPHGSf/dodr5MYFWdA5/1qLXVBkFnp1tTLc+MDDMaIummjrthaS9G8xnv8+/795Zq0Fj+GRxgAAAABJRU5ErkJggg=="},6256:function(e){"use strict";e.exports="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAQKADAAQAAAABAAAAQAAAAABlmWCKAAALjklEQVR4Ad1ba2wU1xU+M7uzfmAMpODFCQ8H8IMCogpKGrVSZKlpEqQQF8jKNmlTaByaJuRHErUhIT+o8iNNU9oqTZSSKkU0kbEzsgNOIiW/CmklmkqOEI2KxdMYiL2AAdevxbsz0+/c2bter3dt78yujX2l2fs+93znnnPvuXdmFcpwsIgUSfL0+vWzZxcWLiFFWWYZxjqyrDJUVqB+IdIFsp2IFaXftKwu1LeRx3NSUZTWsKqeG4pEzi/T9f/JtqjHEJkLMWbdkpTAmcELmzeX+jRtF8q2gK4WpW0gZuZ5TPlEq0TEdfLhek+0MoxYN8PhV29vampDA67jH27rOghibqgwQ8xM+6ZNxbma9gxyP0K+DOUqZllF3kKsIE5vLMuy4vqaCvKgeQrPxxHTfHOxrl+SY7vhPz2m4kbiwTnbVVOzFMz9HMlf4CkE02YUuGPaTHdUsAVi0ybqx/h7VaJ3ihobz3JbDIai9IMjJhl867p13ttLS59QLetPAO0BaNYFR/TSZjuqHRC8Cbv65TenT7+9rrU14kQIaTPMMDs3by73aFo90qsB3DtpwBMlZQsiguKTEct67I7GxuPpCgFaNPEgwFdXb/d4vUeRXjul4Jlt1jieAKKVmqIcCVZX72AeJ45ogo0F0UBA61LVP2DMp6IDpCW8dJhy2NYU/Sxr/2Aw+HTJ4cM3J6IN40qLwbdXVubk+f1NkPgPp3zWx5KO2CjIwCT9fcgwqhbpOgvBFkyKfmPOIoOHM+PL9fs/APgHb2nwDNBehD3g+weax6O3b93qE9qbArzokqpOgocn1wzCD6HdmMJKRWcKy9nx+qffMNaTrodSmcNYoJTZc+b8Lqr245rKFAJNPjQ7YUTfC6rqm4hT8p9UADz7wZqabej49C2v9snh2+Zgb9E/A5aUu8MoyTD4K1u2rDAN49+Y/ULQTyqkVOPeguW8CPbhoHVvcWNjGwAD4nAYAY7BU2WlxzDNAwA/G81G1A93m1YpxlCgKkrzxUAgV2CMY38UwCt+/08gpTVQ/VF1cf2mV5IPY0TLNVWtS2Q8ZgIsmW+qqhZ58vJOoxF7VzNHADZqNoWIEg6vLGpqOidNYQRIT27u41HwMcHYfWfEL2P1ml6v9GQFKAGUZ//Sxo23eXNy2lB6G54RghEtZ8KP7Slet0yzYqGuX2UtiAHVNG3HjAbPE8ieoqLMxZXbrzjHRSrPPkvCUtWNXOA2gB5ZfEjLxuOWuWh/zHoVBQJexs6LHXVv2rRoyLIqIAiWkONhcPFJSn4+acuWgbIg7ZhWYkdraIjCZ8+SdfMmKWpMcRObjZ/HjoDJWdphmqVLiP7LXCoRn28nYIv0+BSSt4BdUf6DD1JBbS2peXnJG7ksNXt7qff992nwyBFSPPLONE2i0QNTjqY9j551yoVAIA8npyswgnxhI2nSE82hNb7Vq2nezp22QUkaLrRJkgBfsaRIg2Y3xglfuEC4EhuuSydlL4aDqmn61Tyvdyn6zgJ4h9Rg81DPvPvvHwmeGWIGnTIp+3MsQ1T18x/C4RQa5zLkRVS1TA2b5p2CkO0tOaMJZtRZs6JkLBr47DPq3rWLQl99BfwOhYB+bFaDX3xB3S+/LGLOc1ALcfnsRrCCCugoSinf3a9B3nSs/lFiImKmsBD2HTpEkY4OuvHaaxQ6fJisMN5tTFQQ3A5AebHrP3iQet56iyJQ974PPxS0XWmU5NXeDvl9xRoVDK8WApCVbmK2eSxOnvnzbRXVNOrZu5euv/46mYODNuXoLCYdJloXCQap+5VXqE/XsTRjbY5EyFtcLGi72aUSxjTZIVLBcmlChfMsBAB6VPDoo6TwTgDGebUe+vpruvrss2IWjatXh7VBakU0Dp8/Tz3vvkvdL75IkYsX7e2OaUDlC2pqbM/FOXeJPZnVO9kZmIMUZzITsFDlrF1L8/fsod4DB+jml1+SFQqRNTBAfU1N1N/SQr677qJcPJ6iImLfwbh0iUJHj9LQiRP29iZ3D2hQ3n330WyAV+fOtfljYWUoYB2Zy3v/YjyZE0CUOXXOHCp8CueObdto4PPPqb+5mawbN+B8qzR07BgNtbYK8DywBTUXZonYgqkoWFALqqoo/5FHSPH5MrI8RdkajuzjfpE3ijyzAojOoFipc3Jo1oYNlPfAAxSBiodPnRIzbXR2ktnfL8xBzc0l78KFpJWXk1ZRQVpJCanwKGP2LjVimH33KZum7Qq7p5aCgmQcMYP0lZWRDyBnPfyw6CC3yKSureybgnSmitkEJicwIAkqutrHgEu7lvWTwxGPYvEieAGslSHj0LlOk1uANeDTD3zyCYXPnRPbpVZaKsxEOFOTJwTck1pB/oDhBksiTRjOmgP8zePHqfuFF8RpsXD7diqsqxO7xNXnnqOh07iNG8tPcDZqql4WqWqPFwdL/uri7lStMl2uYC2YB9eWFzoZCrdupdx77hm5BcrKbMaKcsZrqiq/U/9xNseJ0YZ680Io3FlWdanu0AzfypV2XpbFOmUtwdp/wosDwX+gAXwm4G9ywFWWQzxwOVSyMlmXjVhsP/B9gJ0PmO1iDBfHYdgSmX199sxmg+F4mpgns6dHXLnFFztJ4/OeU2pfMNiBaQdF8fLACR3hrfERWIRsLmJwm3ny+j/9dNh8HHEsOvUZAwOnPH9sbzf7V636FtThuyh2fNlm4ARnXL9O2ooVwulxzlfynrxNmdeuUe9774nDVcyHSN587FJ8yQZ6+4qbm1v4GkjpCwTm93s8HRBvjpt1gC8smDHvokX20XVsNtKrxeyHccfAwRV4e60Lq4axaoGunxECgAlYndXVrVgDvwP6jrWAmeOZymbIwCrN10onuw1j7bd1Pcz3AbAqLGOW1ZgJxpnBbD6Z4BF4dYAX3xXK2bbUUOgdEL+Cx/VtYyaYzBINxnYtFAr9HrFQViEA1oL5LS19OL7uiVZkW5OzhG9MshLTn0sOHuxhzNxaaoDoqYbDH8Ag+PJONhblM+SHMQ3iy5e/xOOJCUBoQXNzF14bbUODsNhw41tO57Tt+UUggR3Fus6n39gExwTA+LjiH4bxEZLHsB3OnLUAXi4Qn7lmGPWJ8wjMIwMaKp1btizBa6N/oaYIzwghjWw9LXL8iX03bqfvLaqvj30ZIjkfBY61oLi+vgMa8Dw68sfIMXWRnaZNLHlXlJeSgWccowTAhSwE/4EDjYh3QxCRaSkE2+Nju3/D39CwjzExtsSQVADcCB3MItP8DeL6abkeYA1TTPNQxDB+zVgSgct8SgEIIej60BHDeALpRmiBfRSTPW/VmGcevGLZO3jEsmrwxXhoLFYhnLEDL4pooVyurd0H2rUgPnX/EBmbVSg5wLPJEn3kr6iopd27+YyfVPUlqTE1gBsxATxmUSTyJOJXox1TqpQkPAWxzZNl/XYwN/enyu7d5njgmUe0mXhgbcCHx7Xo8Qakjde1CJNxjSYGSvFjzzrPfhDXey8taGjYPxHgklpaAuBOLIQrgYDf9Hg+xqD8bQG/vOOqtGlxJxeBbZ2vxsJQ4zbDMDYkenkToT2uCSQSYekW6XoXztPfx8XEYxAIv1fgMJlmwc4NK98NPFuvGsbdTsAz065mjbUBi2MRXmY8jpl4BvT4TTOrI9+4uqIt6MT/2KqOIREsqxP3F2+HVHX/4oaGTp6U+KbppF0zyUJgBi4HAgUwiyfB3DaULQf+HDDCnqQ9RnpmItRbALFvqzmPDwSVc7h2+5sXdxcLWlp65djpAE5s61oA8QTBkEqVlerFBQv8PkWpwz1THSbujlgb+4CFZjHNk+NzGQe7Lu5TfQiyE4V/jXg8e7va2oL4h6iBThkzN8mAPXwGfsGs0AiO+e+1S8rLS/CvzuU4XJVDGBUwl6VoUcJDwVmZJyJFucZ5hPMAfB7fGbXxwgZP7uxl02znuzswCqu3adtNM/P7fzVZgkVauHi3AAAAAElFTkSuQmCC"},7655:function(e){"use strict";e.exports="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAQKADAAQAAAABAAAAQAAAAABlmWCKAAATPElEQVR4Ae2baZIjuW6AM1Mpqat6Gb93Kd/Dl/FhHWE7ZroWLSn5+wAixVKrZ95fRw+7s0iCIMAFAMFF43/+x79fB8LxvAzTOA78H14Oi6Dh824zfD+cI/1puxn2fCJsNvOwnE8B//31GLAncDcTlQnSuVyvw7Jchu1MHcLzt38ME/WO76/D+8v34fWYdL982kb59/fTcKXO16fdcKae7TidM95vZ9p0DvgEj3/+9nXYP38F/zL8/t//NRxOl2HejMMOXvvnL8Nm3g6vv//PIM0Lvfu0naLMPp6XK+kJ/Gk4ns7DFNx/4T+zo2wwLglwBhI2xohFesxypyZmt+rFbI3UB/5AAhCPRusybIZL8JFXzC4lPX8lwPwqAdIGZ4L3WTjTOfGJs6Hs2tIn01ekl3/T+QqXGx/F+wQRy4I2daQJK/LXYVbUDMbrl6A135dbu/BWeFf/T2Fd3aDR6lWdiot+j/MB1uj0bXlULmygoz8rE84AiCWS+u8XmRWWgFu5eXH6euQi38OSTMKLfta94RbOWh6sq7zx7GC3DkcDQGA2oz1Vx7jVa3Al4CNOn2cANC6GEwYiEYfh7ZhGUDl5O2V6uUwhguJM8zgsGBDDK/WFKb5lBCuvKG8xOhGguVnG4QD+mx90qWVroviVco3aNE1hPO1sqiJqiEa+YTRDBcDfYaQvc+LL/4AoY9OGE7wW4JvLGEZTQ6uo23bL7KO0zhtUSCOo4c/W/bp/58+f5pwgjFgZwZoVl8FrM2yfWDpuy+BmWFjSDMuFIWVW/nIZ3G9YBlkqr/MwLfMwMvTOffG/Ig3X6xT51QgyXQqIy6DxCQPGagcOyx30NHwn2r8Bb6adsQwC38y0Dbg0qdItg0oTyyCz7zK4ZSWfv7/lev5IBa6I8GupAAOgFU0VoOOnrPd6MGYFAPehCsy5olx3Zxo2DAf4vfk1FVBEDaqiKoAW/6ACWuteBbbQWjbgM/gv0CoV2MHrPCUf4S+0Tfrns36AK0OqwIlR/FsFctyHWQ/PoGg5u4qaYmOwrGzYvqlASgBwVnXD6Zzeobg/SABiWZ6g5RNiNxJf/drUF3+9RkU6eKp2/D+H+o2hehfFn0+QOLan8Ef8BHmrApZtULWFWJrKn7iW2cdSASVAWnPoNUh2vGyAltJgmXpX6ZsNwFK3ATiccgB2Mo4G31xh8zUAup/agAG8i41rA1D805m5Bk873rdHnFgB6JCu8L65tqqMfHVtyhWWz4bOnoFL0+YXftBkRssVdhXCD8iFYFzXVAcjR8CyKtdqRRoqPVyJANBgpAkhSTYriop+1k8pK7ri3Mr1WpJ2Tkgj3WA3Hh/5Swt8/7U29jzsJOa9lUm/eCRsnrSYBLIhEhKaUrpZ77XYUUyaGRQXbm5qtLCGkXU366SIC1OStD5X3WdmwzAy+6atK52RmXC4iv/I2myd4Em9KAsBThxd3InGK2Rj0GDmWd8D/0ob8B+CvrSLBzQnmjnK18++tTapjpbNy4ndHGHBQl5puG03HbDpsjo8aBliTyNFwPrWbvDiagBsAXfAATFIp3aD0zUH4OLukQ5aT56XczpSSy4m5HM3uOC4q7vZjhbT6AX8sBOMwOV8jFVIFZDWwm5wRMFVy+iPfIJH7gYv45Jl9Gth4BcHjMHTmUv5i2b/mn/m399SAh75AcuyWf2A47IMeyy++jXNOcIO2R/vx4CdwS0jKI5WPlzhpgLL7oR1vuIHHPED+JofoKQYyg8w50yrA+UK77HKvR8wQ+tpUmIuwx/QuvkBrALAN7TvBXj5AcfwAzCKzQ/YdX6ASh0NyLhPCzbfwypfcY9zD+vL+nThGRe84kdlfwUrOo9oVNnPaczPuLuGI8pQy2Czb4NlOT+5lt6WQXRtzHrOvEbw08MTodsy+MTStdGQiu/SCWWbVfwv2BXXdfNnNk3agJMxOMFXiWp+wPNugh9+ADbnCP6E/VldYZY/l8Er8KR5WwbtY/kBusLs6XSJZYEjRFwD4Fq7wrp04NIy6jpaiWNLAyY8YUHHkaNDBSv6xvUVj4rVBsscCMle6KBx1AVebCNPwRUzXrRuceJXXj+g0sY265anGzL/lcPDAxGNmCEcijY6kRbOt6YbziOYFO7xKl+xpE3fx1le9StWHXRiev4tTUkP/5BuPFbYXX4un9xY8TD8DPYB3qz3R1ir32gEzQ6v8hX/wMs2tO9h2R3dwrXlslnzHZ0f4IF74zNrFAxlYJyQpYP1aTcjWiVU9IYDBxy0qJ+U0jyEIwT+2NHaoLPyqc+57/nbgbWMwnOjLV/b4SdvcZg5jGCmi4YHpuFQEhcd0CJtWcH0KG20e555GxYtR6+M4Mx6bbBs1sNr6cBlhDasoxOHFwHHBUX+AlfjYpCOAyBG0Tf2uOtCvPD1cOuYdwCMpeJEKJLGwrTamMXYDEUeWrrapj2TcTNketvW+ExTBo1KS181Mi89zxOyF5D+VcP8/Ns/o+9cELRlkNnDuzM8c2tz5mTF8LSbWXtvm6Hw7YEfN29hgJ732zhlEbck4Iz3uHMDRXj68ltshze7HZ7kdrhya2N4ft5HvGwPIQHPnz/hB+QGy0NLJeDTbjtc8Ozc3iplT9++Dfunz4Ev7sThpzPq0dkOuDdXVpSmkmi7LbOP0tCvmD2eIz9Pbes3oZ9aylCDFaaTkRsjxTdwxbG8qUYPE8cgDVoXKEV/pI7fhAMlbKS+Ut6Xq9Tm3aVp8yUnqYA1uD5K1oeGPIRTodqXZdlWd4iq+1pfPIxIn5+Pby/R6LwbTManOOdjdq/b4dRmaoMH52GmLXJLWxJwen8P2PHC4SSzYCgJCJ/eEyOC93XWO3E3eHx7HeThABzHdiyP1KmjRwYmDkUpOzG7tki+tsPZWxiA49uWZmgzLqRfuONjnwp8PCtt2Cg8QeEnaCoBtt0y+yiNkTZpi7wbnN8/DIDrKQeX7XJ0vrDRaHcE40LnICRCfzl6UF0clMttM9QPwNI2Q9MW0WcA4nIUngfE1gGga/yFJx10AN4ZkPtTYQ774z7B0yn6ORw4+WUaYwBs/wFz7sBc6ZhbcQc74NDUCNp2yxwAV4IrnVdlYgC8WDD0u8H36rQNaqfCF/fPVA416S5G3KUJozWhn9Iyb2diN9gOFUcvRrDQ/cWIZj7qUsfLGGd0Q8fud4NMWtwmy9/BfWWCru1ixEuW2g168+uFiRcj9su20QxWCS51KKvd4NJdjLgfiGDcfwIr36cLZvwIXrCKf4bXwwu34kdlwnr4fbrK7+Oe5n2ZeS5G8n7ePbOj62R6/meIi5EAtJNYrKcIoQLNV3BWhP31xQhHYajABrsyLeiwsiyPxh8qITXm71VACy4P4RpBL1P2e47lkJgT+Jv+fQBwVYDjYd2IUIHb+4CUhDoU3XL6lD21Jb9omH1FYehtQF2O6inVzdCZdFhQZmJiQupmyFMX9di9d3mCH2xA3QztubFBgDR2b35hW5yjDHUiZN17G+DFphedZQN27+1mCAl4gVbZgLgZ4sZow+IhvE6EzhjBDzdDXAPWzdCHzVA1RgNmMP5X0jfcqBZ/qu59/R6uW/qz8qK5xq0tpSo9nUzf2vux7B5u/gabfZNjSD8gbUA5P9qAkbs2Q9zG9DbAJZcQY8Ws/aUNQCe1AdthN8yXHTOQdOuNUEnNz94I6eiUDfj6tB326jgSsND+bW8DtAn6HMddSiadvdmAH98IzXG7S0eM12Nx0oaF5aRucCw3rzHSvVrr0Qi3aFHW7PR6LE6dyTpBC/o4OUknY0tWOvJnNKtcNgu09eSEqWLRFoxu4FDmE5lKj7Y1PiqI2z5ttMtoliUN80GfQs1rNDDjPi3YfA+7z/c4f1b2CK+nW+UVPyorWI9D79Y23vP/V/Isg4qVQcNzYVhyZBLm4WQYJMqxG2HkQlSVgK6elRZwlQSDdJzNXM4SpgHzut16wqt+z7/qRBnVEgeD1dzjoAFcpwbRTYkpWvr48J3blBcPe4IDGGXSk0bubto5QbT4F/7z9+3wo71A+QFuNyvt/bziowr0j6T0t0NvwH3oByCuBvcCE3uBoz66Hzsxg2JrSL9dGo/3ApYr+jqQ7gXqkVTuBdIHWfcCqGPtBdSIj3sB1Zc7CjdD6Masc2MoJ8f2lF6e4KYDZPCsbfKiwgHwsrLVy3Le6oB7aTaglrSg0zoo/Q31jPNjMPEDTBt0dsK1JV82INsBP9sB3J2cA2admXbpqBUtt73y9QHlpeMDOAbNMnE9B6Slce8cdGrWYj8NEv/XmbSsym2E6RgA4qBKw3P/kGWFmwOgj3CrH7RsYKNTuH284juQ/DdvQpzg3/gFDWj5gCvSOPRM6AfaCdcY3+D2UXmsMuP5H799A1SOkOw4XGwHIl845ppxKQ1efX1qmxIdmjoQmeZDNPaZY6dHByL1QuTp65dwhE5ckfnibNcORL40R2zmyMtV4BtHZM62XXeGkjdHXbTDvI3+t28+lv4Cvocb77Fl92osj8R8LA0+tl6acSSGA2dZHYjsOaPwPODggYiEDCOZmF1G9jjlmaDe1mFsac/VOJtTRPoB2HEQImz/6EwQHds5aATP6nwiE9JB/sQtrp3ctzPBw+CZIOd1z0+IcZ4JjtSHdPA90Y4RuAOwf/4MvWdFBJvyPlyxD/2ZoHwuC+cEw3vsBvftTNA+TgxinQmyAcIRUkYMFfdpYQX/s3TVKdw+X7Cq38eFV7FNqfKCVVzwHmeFtXb+kO/o/VCWdWbf2xv6vUD9XsAb1u/tdOiM2B77vUD7vcB3xEwdWMB1dgzaBUVPY1YqcOaFh89ZPA+s3wuIfX3/+HuB8dD9XoD64hyRIq16HYltr6dhf0RiMILxewEsmypwQLT3z2+xF+h/L3BG7SyzjxrSA+K/HonVkVe/HT6AaGDVQk+a30SHHPxQEy5FlgaPctUC3BqANILpCbZVMF5zToi4B5jyXHmc8kjCvDZgS9n9KqDv9m7j2zL4zuaH0QD/Eu3zTNCXZS55mvkNT2CKR8BouXEeidEPMg7E0YHzRsXgEpYWPW9ZhFlW5WuaztpR3+QYPOezw8Y1ACkBlt7qW+Z5wNJo+nBaCkXfcqU089JEOsDwX/Cm3GCUbaGczU/wpe1KgPDkc0s7vImfy7QLi3WEef0++4CwQg1Am9x4XHhsUyhe4EZnkYD2TnBnr4DFQ8S1kU0FgJcK1DvBK3QufM6Aofh7YKEEmK92RPdpsDD9hBGVcDmU1ha+7i4tc7m0Q6Yti3eCkWa9h40wywwTdMyrAo74vP/8NQpGeo0TFiN+2uTSp2U/trQPErWmdvbDKoClFWbZny2DO1abWAVg4syeZ6w6nPdPeTN0nPJmaP/8KZwZy6Z2LyDt8+YYjXeMd/xeaMdKoCjvP7sKsOQxALkMcjOErVlYBaQZA9CWwejjugrQWVeBuEaCWXh6dCTEmZE1+OTU5yeZtoO3AdBNNjgYNtayfgAsV3dX+nGDQ8OgKd2N52pUvJWnDTBvPWc//ybORAO1ISniWd/L0eQrju5ttlHakeZWy3ascLqiWQ3+toH8/PrH/0ZH+lVA/9ownebhvaURhXji6mxLsN4JvsevxkAG18ZFPXBqFTg30SvJOb6/sAq8hO+vlm/OeSLlOaEqMF/e0xGCVL5Op9GsAm84TmEE4fHGK7B8/8OZJe2PX40Bz/fBvhZn1QAuTdtxPfCmCSmIVQAVWJoKxMVILmNpIZ19/q8boP65vJeQPowWp38m98LNkLCfP5dP3buuz+R8Lp/P5BwA/xvWQ1HS96uAA/HhUBRaS3sm53O49VCU9p0fPJM7c1myo6wuRvrn8nF+YAPUFefPz7TB+D5tuY3u4VXH4yuDeQb+h/qWF03jqmcd84/q3JdV/h6/p92ne5ofeLe28FzehQJxp1ZZX8XGYFmdCeZzea2kKuAqkPW8UFECfJF9rwJIGqtA4ll/4z0U+FdwL+izel78PX3yFyPmQZEN7rKDlLTd0t6ey3sVDj4w+fIMJZZBrXvyoX3S8U6QfuRzeS9+UDlGoX4xYunfy6D6ZTAuCch9uDD34SkNJ0bZcqcmDFzV010F9v/2h5O15YwtKB2xjwXzkKPSGnidkDB4DEYYKgYuBotKemK5f3eMTKcrHATFQ/QuDKb40qyDlqJv3jrm742gS/GJ8nKFdYo2fLrC0vOTt3w30iFfPNR7225Z4AJQKZ1WaXImaFaEmw0oL82yU7MHP7MBBxUWPd2Be28DdLbKBuzQf4/SVPALuAv6Ti51mPikvsJLnmUD0jFLHH/750sQ/J3Q/12zAfLVvXUC0uPT1kADuDQdAGlaFn0EUDaAadIjzAHwCVupgGmDZR5jreloEaPskFY9b5IdeXGFE4KOA8f/G32NkDi3r+hW7ABYblVIer8RsTBvhjbMeJ5MkfaFCJIR9MCVd9KuOPm4IiTcvFKTPBKGBOgcGHpHKJ+mCLupg32zUdFZd4NVz8MLBwDcfgDKEYJ/BB4kxk8u5FOf5FxFDMJsnLGiKi/F2FVg5AcPtZPTMXUXp5usKxy0wFvPI+/4yD/eBTYeKd3uDnM3+H+mm2MLhDtYPQAAAABJRU5ErkJggg=="}},t={};function i(s){var a=t[s];if(void 0!==a)return a.exports;var n=t[s]={id:s,loaded:!1,exports:{}};return e[s].call(n.exports,n,n.exports,i),n.loaded=!0,n.exports}i.m=e,function(){var e=[];i.O=function(t,s,a,n){if(!s){var r=1/0;for(p=0;p=n)&&Object.keys(i.O).every((function(e){return i.O[e](s[l])}))?s.splice(l--,1):(o=!1,n0&&e[p-1][2]>n;p--)e[p]=e[p-1];e[p]=[s,a,n]}}(),function(){i.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return i.d(t,{a:t}),t}}(),function(){i.d=function(e,t){for(var s in t)i.o(t,s)&&!i.o(e,s)&&Object.defineProperty(e,s,{enumerable:!0,get:t[s]})}}(),function(){i.g=function(){if("object"===typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"===typeof window)return window}}()}(),function(){i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)}}(),function(){i.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}}(),function(){i.nmd=function(e){return e.paths=[],e.children||(e.children=[]),e}}(),function(){i.p=""}(),function(){var e={678:0};i.O.j=function(t){return 0===e[t]};var t=function(t,s){var a,n,r=s[0],o=s[1],l=s[2],m=0;if(r.some((function(t){return 0!==e[t]}))){for(a in o)i.o(o,a)&&(i.m[a]=o[a]);if(l)var p=l(i)}for(t&&t(s);m(#1 Recommended)
+2. SMTP.com (Recommended)
+3. Brevo (formerly Sendinblue) SMTP (Recommended)
+4. Gmail SMTP (Gmail, Google Workspace, G Suite)
+5. Elastic Email
+6. Mailgun SMTP
+7. Mailjet SMTP
+8. SendGrid SMTP
+9. Postmark SMTP
+10. SparkPost SMTP
+11. SMTP2GO
+12. Microsoft SMTP One-Click Setup (Outlook.com and Office 365) [[Pro]](https://wpmailsmtp.com/?utm_source=wprepo&utm_medium=link&utm_campaign=liteplugin&utm_content=readme)
+13. Amazon SES SMTP [[Pro]](https://wpmailsmtp.com/?utm_source=wprepo&utm_medium=link&utm_campaign=liteplugin&utm_content=readme)
+14. Zoho Mail SMTP [[Pro]](https://wpmailsmtp.com/?utm_source=wprepo&utm_medium=link&utm_campaign=liteplugin&utm_content=readme)
+15. Other SMTP
+
+For most options, you can specify the "from name" and "email address" for outgoing emails too.
+
+All of these powerful features make WP Mail SMTP the best SMTP solution for WordPress.
+
+If you don't know which mailer to choose, see our [Complete Guide to WP Mail SMTP Mailers](https://wpmailsmtp.com/docs/a-complete-guide-to-wp-mail-smtp-mailers/?utm_source=wprepo&utm_medium=link&utm_campaign=liteplugin&utm_content=readme).
+
+#### SendLayer
+
+SendLayer is our #1 recommended transactional email service.
+
+Its affordable pricing and simple setup make it the perfect choice for sending emails from WordPress. It also has open and click tracking and email logs.
+
+SendLayer is reliable, fast, and easy to set up. You can send hundreds of emails for free when you sign up for a trial.
+
+Read our [SendLayer documentation](https://wpmailsmtp.com/docs/how-to-set-up-the-sendlayer-mailer-in-wp-mail-smtp/?utm_source=wprepo&utm_medium=link&utm_campaign=liteplugin&utm_content=readme) for more details.
+
+#### SMTP.COM
+
+SMTP.com is a recommended transactional email service.
+
+With over 22 years of email delivery expertise, SMTP.com has a reputation for being one of the most reliable senders on the internet.
+
+You can start sending emails in minutes and benefit from 50,000 free emails in your first 30 days.
+
+Read our [SMTP.com documentation](https://wpmailsmtp.com/docs/how-to-set-up-the-smtp-com-mailer-in-wp-mail-smtp/?utm_source=wprepo&utm_medium=link&utm_campaign=liteplugin&utm_content=readme) for more details.
+
+#### Brevo (formerly Sendinblue) SMTP
+
+Brevo is a recommended transactional email service. It serves 80,000+ companies worldwide.
+
+Brevo is reliable, fast, and gives you 300 free emails per day.
+
+Read our [Brevo documentation](https://wpmailsmtp.com/docs/how-to-set-up-the-sendinblue-mailer-in-wp-mail-smtp/?utm_source=wprepo&utm_medium=link&utm_campaign=liteplugin&utm_content=readme) for more details.
+
+### WP Mail SMTP PRO
+
+In addition to native Microsoft, Amazon SES, and Zoho Mail integrations, WP Mail SMTP Pro provides access to many other powerful features.
+
+[Click here to purchase WP Mail SMTP Pro now!](https://wpmailsmtp.com/?utm_source=wprepo&utm_medium=link&utm_campaign=liteplugin&utm_content=readme)
+
+### Email Log
+
+Email logging is a powerful feature that keeps a record of all sent emails in WordPress. Email logging helps you to archive, audit, resend, or test email delivery and formatting.
+
+Our [WordPress email logs](https://wpmailsmtp.com/log-emails-wordpress/?utm_source=wprepo&utm_medium=link&utm_campaign=liteplugin&utm_content=readme) also include:
+
+#### Email Log Details
+
+Our email logs provide a complete history of all emails sent from WordPress. View the subject, sender, recipients, content, headers, open and click rates, delivery status, source plugin, and more!
+
+#### Resend Emails
+
+Resend emails individually or in bulk, whether they failed or were delivered successfully. You can also forward important emails to an alternative email address.
+
+#### And many more Email Log Features
+
+Store all email attachments, export email logs, print emails, see delivery status, and more.
+
+### Email Reports
+
+Review weekly sent and failed emails in a dashboard chart.
+
+Email reports make it easy to track deliverability and engagement. Open rates and click-through rates are grouped by subject line, making it easy to see the performance of your campaigns or notifications.
+
+#### Weekly Email Summary
+
+Get statistics about WordPress emails, including how many emails are being sent and which ones are being opened and clicked. The Summary also shows you deliverability statistics without the need to log in to WordPress to check them.
+
+#### Track Email Opens and Clicks
+
+[View open and click stats for WordPress emails](https://wpmailsmtp.com/enable-wordpress-email-tracking/?utm_source=wprepo&utm_medium=link&utm_campaign=liteplugin&utm_content=readme), grouped by subject line in your Email Report.
+
+### Email Alerts
+
+If your emails stop sending, get notified instantly via Slack, Microsoft Teams, Discord, SMS/ Twilio, webhooks, or email (via secure API).
+
+In combination with our email logging and resending features, Email Alerts ensure that no important email will ever be lost.
+
+### Backup Connection
+
+Configure an extra connection that kicks in if your primary connection fails. WP Mail SMTP automatically detects connection issues and automatically switches to the backup mailer. It will also automatically retry emails that failed.
+
+### Smart Conditional Routing
+
+Create criteria to send different types of emails using different mailers. Filter by the contents of the email Subject or Message, From or To addresses, the plugin that generated the email, and more.
+
+This allows you to mix transactional and marketing providers to improve deliverability.
+
+### Rate Limiting
+
+Control the number of emails your WordPress site sends in a specific amount of time so you stay within your SMTP providerās rate limits.
+
+WP Mail SMTP allows you to specify the maximum number of emails that will be sent every minute, hour, day, week, or month and automatically queues emails to stay within those limits.
+
+### Optimized Email Sending
+
+Are emails slowing down your site? Let WP Mail SMTP queue your emails for better performance.
+
+With optimized sending, emails are queued in the background and sent when your server has sufficient resources, avoiding bottlenecks that can slow down your site.
+
+### Manage WordPress Emails and Notifications
+
+Control the default notifications WordPress sends. Use a simple switch to disable specific types of notifications if you donāt want to receive them.
+
+### WordPress Multisite
+
+#### WordPress Multisite Network Settings
+
+For users running a multisite network, save time with a centralized location to easily configure your SMTP settings for all sites.
+
+#### Manage Multisite Email Logs Easily
+
+Network Admins can view and manage email logs for subsites with easy switching and dashboard views.
+
+### Expert Support
+
+We provide [limited support](https://wordpress.org/support/topic/wp-mail-smtp-support-policy/) on the WordPress.org forums. World-class one-on-one email support is available to [WP Mail SMTP Pro](https://wpmailsmtp.com/?utm_source=wprepo&utm_medium=link&utm_campaign=liteplugin&utm_content=readme) users.
+
+#### White Glove Setup
+
+If youāre not sure how to fix your emails, sit back and relax. Weāll set up WP Mail SMTP for you!
+
+White Glove Setup includes installation, configuration in WordPress, DNS configuration, full mailer setup, and testing. White Glove Setup is available for our recommended mailers: SendLayer, Brevo, and SMTP.com.
+
+### Credits
+
+WP Mail SMTP plugin was originally created by Callum Macdonald. It is now owned and maintained by the team behind [WPForms](https://wpforms.com/?utm_source=wprepo-wpmailsmtp&utm_medium=link&utm_campaign=liteplugin&utm_content=readme) - the best drag & drop form builder for WordPress.
+
+You can try the [free version of WPForms plugin](https://wordpress.org/plugins/wpforms-lite/) to see why it's the best in the market.
+
+== Installation ==
+
+1. Install WP Mail SMTP by WPForms either via the WordPress.org plugin repository or by uploading the files to your server. (See instructions on [how to install a WordPress plugin](http://www.wpbeginner.com/beginners-guide/step-by-step-guide-to-install-a-wordpress-plugin-for-beginners/))
+2. Activate WP Mail SMTP by WPForms.
+3. Navigate to the Settings area of WP Mail SMTP in the WordPress admin.
+4. Choose your SMTP option (SendLayer, SMTP.com, Brevo (formerly Sendinblue), Gmail SMTP, Elastic Email, Mailgun SMTP, Mailjet, SendGrid SMTP, Postmark, SparkPost, SMTP2GO, or Other SMTP) and follow the instructions to set it up.
+5. Need more help? Get support with [WP Mail SMTP PRO](https://wpmailsmtp.com/?utm_source=wprepo&utm_medium=link&utm_campaign=liteplugin&utm_content=readme).
+
+== Frequently Asked Questions ==
+
+= Which email providers does WP Mail SMTP support? =
+
+**SendLayer**
+
+SendLayer is our #1 recommended transactional email service.
+
+Its affordable pricing and simple setup make it the perfect choice for sending emails from WordPress. It also has open and click tracking, email logs, and email list management.
+SendLayer is the best choice if you want a mailer that's reliable, fast, and easy to set up. You can send hundreds of emails for free when you sign up for a trial.
+
+Read our [SendLayer documentation](https://wpmailsmtp.com/docs/how-to-set-up-the-sendlayer-mailer-in-wp-mail-smtp/?utm_source=wprepo&utm_medium=link&utm_campaign=liteplugin&utm_content=readme) for more details.
+
+**SMTP.COM**
+
+SMTP.com is a recommended transactional email service.
+
+With over 22 years of email delivery expertise, SMTP.com has been around for almost as long as email itself. They are known among internet providers as one of the most reliable senders on the internet.
+
+Their easy integration process lets you start sending emails in minutes and benefit from years of experience. SMTP.com provides users 50,000 free emails the first 30 days.
+
+Read our [SMTP.com documentation](https://wpmailsmtp.com/docs/how-to-set-up-the-smtp-com-mailer-in-wp-mail-smtp/?utm_source=wprepo&utm_medium=link&utm_campaign=liteplugin&utm_content=readme) for more details.
+
+**Brevo (formerly Sendinblue) SMTP**
+
+Brevo is a recommended transactional email service.
+
+They serve 80,000+ growing companies around the world and send over 30 million emails each day.
+
+Their email deliverability experts are constantly at work optimizing the reliability and speed of their SMTP infrastructure. Brevo provides users 300 free emails per day.
+
+Read our [Brevo documentation](https://wpmailsmtp.com/docs/how-to-set-up-the-sendinblue-mailer-in-wp-mail-smtp/?utm_source=wprepo&utm_medium=link&utm_campaign=liteplugin&utm_content=readme) for more details.
+
+**Gmail SMTP (Gmail, Google Workspace, G Suite)**
+
+Often bloggers and small business owners don't want to use third-party SMTP services. Well you can use your Gmail or Google Workspace (also known as G Suite/Google Apps) account for SMTP emails.
+
+This allows you to use your [professional email address](http://www.wpbeginner.com/beginners-guide/how-to-setup-a-professional-email-address-with-gmail-and-google-apps/) and improve email deliverability.
+
+Unlike other Gmail SMTP plugins, our Gmail SMTP option uses OAuth to authenticate your Google account, keeping your login information 100% secure.
+
+Our plugin also offers the "One-Click Setup" option, which allows you to start sending emails from your Gmail account with just a few clicks. It eliminates the need to manually configure your own Google App, which is a technical and time-consuming process.
+
+Read our [Gmail documentation](https://wpmailsmtp.com/docs/how-to-set-up-the-gmail-mailer-in-wp-mail-smtp/?utm_source=wprepo&utm_medium=link&utm_campaign=liteplugin&utm_content=readme) for more details.
+
+**Elastic Email**
+
+Elastic Email is a cloud-based email marketing platform offering tools for email campaigns, automation, transactional emails, and analytics, designed for businesses of all sizes. Elastic Email offers a limited free plan where you can send emails to your verified addresses.
+
+Read our [Elastic Email documentation](https://wpmailsmtp.com/docs/how-to-set-up-the-elastic-email-mailer-in-wp-mail-smtp/?utm_source=wprepo&utm_medium=link&utm_campaign=liteplugin&utm_content=readme) for more details.
+
+**Mailgun SMTP**
+
+Mailgun SMTP is a popular SMTP service provider that allows you to send large quantities of emails. They provide 5,000 free emails per month for 3 months.
+
+WP Mail SMTP plugin offers a native integration with MailGun. All you have to do is connect your Mailgun account, and you will improve your email deliverability.
+
+Read our [Mailgun documentation](https://wpmailsmtp.com/docs/how-to-set-up-the-mailgun-mailer-in-wp-mail-smtp/?utm_source=wprepo&utm_medium=link&utm_campaign=liteplugin&utm_content=readme) for more details.
+
+**Mailjet SMTP**
+
+Mailjet is a global email sending service that allows you to design, send, and track marketing and transactional emails. They provide 6,000 free emails per month (up to 200 emails per day).
+
+WP Mail SMTP plugin offers seamless integration with Mailjet. By connecting your Mailjet account, you can enhance your email deliverability and ensure your WordPress emails reach your recipients' inboxes.
+
+Read our [Mailjet documentation](https://wpmailsmtp.com/docs/how-to-set-up-the-mailjet-mailer-in-wp-mail-smtp/?utm_source=wprepo&utm_medium=link&utm_campaign=liteplugin&utm_content=readme) for more details.
+
+**SendGrid SMTP**
+
+SendGrid has a free SMTP plan that you can use to send up to 100 emails per day. With our native SendGrid SMTP integration, you can easily and securely set up SendGrid SMTP on your WordPress site.
+
+Read our [SendGrid documentation](https://wpmailsmtp.com/docs/how-to-set-up-the-sendgrid-mailer-in-wp-mail-smtp/?utm_source=wprepo&utm_medium=link&utm_campaign=liteplugin&utm_content=readme) for more details.
+
+**Postmark SMTP**
+
+Send emails securely using your Postmark account with our API integration. You can sign up for a free trial without a credit card, which allows you to send up to 100 emails per month.
+
+Read our [Postmark documentation](https://wpmailsmtp.com/docs/how-to-set-up-the-postmark-mailer-in-wp-mail-smtp/?utm_source=wprepo&utm_medium=link&utm_campaign=liteplugin&utm_content=readme) for more details.
+
+**SparkPost SMTP**
+
+SparkPost is a transactional email provider that's trusted by big brands and small businesses. It sends more than 4 trillion emails each year and reports 99.9% uptime. You can get started with the free test account that lets you send up to 500 emails per month.
+
+Read our [SparkPost documentation](https://wpmailsmtp.com/docs/how-to-set-up-the-sparkpost-mailer-in-wp-mail-smtp/?utm_source=wprepo&utm_medium=link&utm_campaign=liteplugin&utm_content=readme) for more details.
+
+**SMTP2GO**
+
+SMTP2GO is a transactional email provider that offers a robust and reliable email delivery service with global infrastructure, real-time analytics, and advanced security features. If you're just starting out, you can use SMTP2GO's free plan to send up to 1000 emails per month.
+
+Read our [SMTP2GO documentation](https://wpmailsmtp.com/docs/how-to-set-up-the-smtp2go-mailer-in-wp-mail-smtp/?utm_source=wprepo&utm_medium=link&utm_campaign=liteplugin&utm_content=readme) for more details.
+
+**Microsoft SMTP (Outlook.com and Office 365)**
+
+The Microsoft 365 / Outlook mailer is a great choice if you already use Microsoft's email services (Outlook, Office 365, Microsoft 365, or Hotmail). Due to the fairly complex manual Microsoft App configuration, we recommend the One-Click Setup, which will get you up and running in just a few seconds.
+
+Read our [Outlook and Microsoft 365 documentation](https://wpmailsmtp.com/docs/how-to-set-up-the-outlook-mailer-in-wp-mail-smtp/?utm_source=wprepo&utm_medium=link&utm_campaign=liteplugin&utm_content=readme) for more details.
+
+**Amazon SES SMTP**
+
+Advanced or technical users can harness the power of Amazon AWS (Amazon Web Services) with the Amazon SES mailer. With this integration, you can send a high volume of emails at a very reasonable rate.
+
+Read our [Amazon SES documentation](https://wpmailsmtp.com/docs/how-to-set-up-the-amazon-ses-mailer-in-wp-mail-smtp/?utm_source=wprepo&utm_medium=link&utm_campaign=liteplugin&utm_content=readme) for more details.
+
+**Zoho Mail SMTP**
+
+Send emails using your personal or business Zoho Mail account, all while keeping your login credentials safe.
+
+Read our [Zoho Mail documentation](https://wpmailsmtp.com/docs/how-to-set-up-the-zoho-mailer-in-wp-mail-smtp/?utm_source=wprepo&utm_medium=link&utm_campaign=liteplugin&utm_content=readme) for more details.
+
+**Other SMTP**
+
+WP Mail SMTP plugin also works with all major email services such as Gmail, Yahoo, Outlook, Microsoft Live, and any other email sending service that offers SMTP.
+
+You can set the following options:
+
+* Specify an SMTP host.
+* Specify an SMTP port.
+* Choose SSL / TLS encryption.
+* Choose to use SMTP authentication or not.
+* Specify an SMTP username and password.
+
+To see recommended settings for the popular services as well as troubleshooting tips, check out our [SMTP documentation](https://wpmailsmtp.com/docs/how-to-set-up-the-other-smtp-mailer-in-wp-mail-smtp/?utm_source=wprepo&utm_medium=link&utm_campaign=liteplugin&utm_content=readme).
+
+= Can I use this plugin to send email via Gmail, G Suite, Outlook.com, Office 365, Hotmail, Yahoo, or AOL SMTP? =
+
+Yes! We have extensive documentation that covers setting up SMTP most popular email services.
+
+[Read our docs](https://wpmailsmtp.com/docs/a-complete-guide-to-wp-mail-smtp-mailers/?utm_source=wprepo&utm_medium=link&utm_campaign=liteplugin&utm_content=readme) to see the correct SMTP settings for each service.
+
+= Help! I need support or have an issue. =
+
+Please read [our support policy](https://wordpress.org/support/topic/wp-mail-smtp-support-policy/) for more information.
+
+Limited support is available for WP Mail SMTP users via WordPress.org support forums.
+
+Email support and set up assistance is available to WP Mail SMTP Pro users.
+
+= How can I migrate from a different SMTP plugin to WP Mail SMTP? =
+
+Want to switch from your old SMTP plugin to WP Mail SMTP? We made it easy for you to migrate your SMTP settings in one click!
+
+WP Mail SMTP will automatically detect your existing SMTP plugin (Easy WP SMTP, FluentSMTP, etc) when you run our easy Setup Wizard. Just click Import to copy your settings over.
+
+Our one-click migration tool supports all of these plugins:
+
+- Easy WP SMTP
+- FluentSMTP
+- Post SMTP Mailer
+- SMTP Mailer
+- WP SMTP
+
+= Is WP Mail SMTP available in other languages? =
+
+We know that majority of people do not speak English, so we professionally translated WP Mail SMTP and WP Mail SMTP Pro into the following languages:
+
+- Spanish (Spain),
+- German,
+- Portuguese (Brazil),
+- Italian,
+- French,
+- Japanese,
+- Polish,
+- Dutch,
+- Russian,
+- Turkish
+
+= How can I increase plugin security? =
+
+The WP Mail SMTP team takes security very seriously. Not only does the plugin follow all security best practices, but we have several options available to ensure your site is safe and secure.
+
+- Direct SMTP mailer integrations (recommended), such as SendLayer, SMTP.com, Brevo (formerly Sendinblue), Mailgun, SendGrid, Postmark, SparkPost and SMTP2GO, use the official provider APIs. This means you never enter your username or password in the plugin settings and these credentials are not stored in the database. Instead, we use tokens or API keys which are much more secure.
+
+- When using Other SMTP mailer, we provide the option to insert your password in your `wp-config.php` file, so it's not visible in your WordPress settings or saved in the database.
+
+= I found a bug, now what? =
+
+If you've stumbled upon a bug, the best place to report it is in the [WP Mail SMTP GitHub repository](https://github.com/awesomemotive/wp-mail-smtp). GitHub is where the plugin is actively developed, and posting there will get your issue quickly seen by our developers (myself and Slava). Once posted, we'll review your bug report and triage the bug. When creating an issue, the more details you can add to your report, the faster the bug can be solved.
+
+= Can you add feature x, y or z to the plugin? =
+
+Short answer: maybe.
+
+By all means please contact us to discuss features or options you'd like to see added to the plugin. We can't guarantee to add all of them, but we will consider all sensible requests. We can be contacted here:
+[https://wpmailsmtp.com/contact/](https://wpmailsmtp.com/contact/).
+
+== Screenshots ==
+
+1. WP Mail SMTP Settings page
+2. List of mailers with Other SMTP settings example
+3. Backup Connection (Pro)
+4. Setup Wizard - Select your mailer
+5. Setup Wizard - Example mailer settings
+6. Email Test page
+7. Email Log settings page (Pro)
+8. Email Controls settings page (Pro)
+9. Email Log archive page (Pro)
+10. Email Log single page (Pro)
+11. Email Reports - Email Log statistics grouped by email subject (Pro)
+12. Email Log bulk Export (Pro)
+13. Email Alerts - Get notified about failed emails (Pro)
+14. Additional Connections - List of connections (Pro)
+15. Additional Connections - Configuration page (Pro)
+16. Smart Routing - Conditional logic for email sending (Pro)
+
+== Changelog ==
+
+= 4.7.1 - 2025-11-26 =
+Added: WordPress playground blueprint file.
+Fixed: Text domain in a couple of strings.
+Changed: Switched Return-Path option to enabled by default to align with WordPress core.
+
+= 4.7.0 - 2025-11-12 =
+- Added: New transactional mailer: Resend integration.
+- Fixed: Recurring task filling up task meta table.
+
+= 4.6.0 - 2025-08-26 =
+- Added: New transactional mailer: Mandrill integration.
+- Fixed: References and In-Reply-To email headers are now correctly preserved for API-based mailers.
+
+= 4.5.0 - 2025-06-05 =
+- IMPORTANT: Support for PHP 7.2 has been discontinued. If you are running this version, you MUST upgrade PHP before installing or upgrading to WP Mail SMTP v4.5. Failure to do that will disable WP Mail SMTP functionality.
+- Added: New transactional mailer: MailerSend integration.
+- Fixed: Microsoft Outlook basic auth deprecation notice dismissal.
+- Changed: Updated the list of conflicting plugins (added Site Mailer, SureMail, Gravity SMTP).
+
+= 4.4.0 - 2025-03-05 =
+- Fixed: Emails queue runner Action Scheduler task deadlock issue.
+- Fixed: Undefined array key "wp_mail_smtp_reports_widget_lite" warning in the dashboard widget.
+
+= 4.3.0 - 2024-12-11 =
+- Added: New transactional mailer: Elastic Email integration.
+- Changed: The "Tools -> Scheduled Actions" menu is now always visible when WooCommerce or the Action Scheduler plugin is active.
+- Fixed: SMTP password and username fields ignored `WPMS_SMTP_AUTH` constant.
+
+= 4.2.0 - 2024-11-06 =
+- Added: New transactional mailer: Mailjet integration.
+- Changed: Improved security for sensitive data (API keys).
+- Fixed: SMTP2GO mailer special characters handling in from name.
+
+= 4.1.1 - 2024-08-15 =
+- Changed: Delete `wp-mail-smtp` uploads folder on plugin uninstall, if the "Misc > Uninstall" option is enabled.
+- Changed: Decreased `PHPMailer` timeout value to 30 seconds from 5 minutes.
+- Changed: Improved Weekly Summary Email sending.
+- Fixed: Missing Reply-To support in SMTP2GO mailer.
+- Fixed: Setup Wizard translations not working correctly.
+
+= 4.1.0 - 2024-07-17 =
+- Added: New transactional mailer: SMTP2GO.
+- Changed: Recurring email queue tasks are now removed after completion.
+- Fixed: Wrong namespace in PHP 8.0x Symfony polyfills.
+- Fixed: All pending background tasks are now canceled on plugin deactivation.
+
+= 4.0.1 - 2024-02-29 =
+- Added: Optimized Email Sending - move email sending requests in the background process and speed up your site.
+- Added: Automatic database table structure migrations after plugin update.
+- Changed: Improved error handling when sending emails.
+- Fixed: Database error while adding debug events if the `wpmailsmtp_debug_events` table does not exist.
+
+= 3.11.1 - 2024-01-22 =
+- Fixed: Setup Wizard texts.
+- Fixed: Compatibility for List-Unsubscribe header.
+
+= 3.11.0 - 2023-12-13 =
+- Added: Filter to customize the capability required for managing the plugin.
+- Changed: Hide test tab movement notice for new users.
+- Changed: Improved keyboard navigation styles for the Setup Wizard.
+- Changed: Removed `WPMailSMTP\Admin\PluginsInstallUpgrader` class and switched to the WordPress Core `Plugin_Upgrader` class.
+- Changed: The "From email" dropdown to the input field in the Gmail mailer.
+- Fixed: PHP deprecation notices in the Setup Wizard on WordPress 6.4 and above.
+- Fixed: Compatibility issue with Action Scheduler lower than 3.3.0.
+
+= 3.10.0 - 2023-11-08 =
+- Added: Filter that allows to use your website's URL for Google OAuth redirect URL.
+- Changed: Improve plugin settings UI, by changing checkboxes to toggles and some dividers cleanup.
+- Changed: Replaced moment.js library to the WP Core's bundled one.
+- Fixed: Translation strings on the Dashboard widget.
+
+= 3.9.0 - 2023-08-30 =
+- Changed: Moved the Email Test tab from the settings page to the tools page.
+- Changed: Removed Sendinblue SDK library because it was deprecated.
+- Changed: Mailgun API instructions.
+- Fixed: Debug Event details popup scrolling.
+- Fixed: Conflict with other plugins (Alt Manager) that made the WP Plugins install page unusable.
+
+= 3.8.2 - 2023-07-20 =
+- Changed: Improved notifications formatting and styles.
+- Changed: Sendinblue rebranded to Brevo.
+- Fixed: Explicitly set "Content-Type" header for the HTML test email.
+
+= 3.8.0 - 2023-04-26 =
+- IMPORTANT: Support for PHP 5.6, 7.0, and 7.1 has been discontinued. If you are running one of those versions, you MUST upgrade PHP before installing or upgrading to WP Mail SMTP v3.8. Failure to do that will disable WP Mail SMTP functionality.
+- Changed: Updated Moment.js library to 2.29.4.
+- Changed: Removed unneeded sodium_compat library.
+- Fixed: Email address with apostrophes in the Email Test page.
+- Fixed: Review request notice display on subsites admin area in WP Multisite installation.
+- Fixed: Setup Wizard playing UA anthem for certain WP sites.
+
+= 3.7.0 - 2022-12-15 =
+- Changed: Improved Action Scheduler data cleanup on plugin uninstall.
+- Changed: Improved performance for database table validation checks.
+- Fixed: Tasks meta database table error.
+- Fixed: Gmail mailer authorization error if the oAuth app already had other non mail scopes attached.
+- Fixed: Email address validation in Setup wizard.
+- Fixed: Removed unneeded composer libraries autoload code.
+- Fixed: Conflict detection for plugin Sendinblue - WooCommerce Email Marketing (v3.0+)
+
+= 3.6.1 - 2022-10-06 =
+- Added: The `wp_mail` function call backtrace to the Debug Events if the "Debug Email Sending" option is enabled.
+- Added: Plugin's DB tables re-creation process in WP Site Health.
+- Added: Debug Events retention period setting.
+- Changed: Updated the list of conflicting plugins (added Zoho Mail).
+- Changed: Improved conflicting plugins' admin notices (display multiple at once)
+- Changed: Switched to the WP Core function `is_email` for verifying email addresses.
+- Changed: Improved the detection if `wp_mail` function is overwritten.
+- Fixed: Gmail mailer not using the correct From Email Address in Domain Checker.
+- Fixed: Setup Wizard steps navigation, when going backwards.
+
+= 3.5.2 - 2022-08-17 =
+- Fixed: The check if `wp_mail` function is overwritten on Windows servers.
+
+= 3.5.1 - 2022-07-14 =
+- Changed: Removed MailPoet from the list of conflicting plugins.
+- Fixed: PHP warning for undefined variable when using the Default (none) mailer.
+
+= 3.5.0 - 2022-07-14 =
+- Added: Check if `wp_mail` function is overwritten.
+- Added: DB table (`wpmailsmtp_tasks_meta`) cleanup after scheduled actions execution. Keeps DB size small.
+- Changed: Updated the list of conflicting plugins (added Branda and MailPoet).
+- Changed: Updated Action Scheduler library to 3.4.2.
+- Fixed: SMTP.com mailer email content-encoding.
+- Fixed: Dashboard widget graph when there is no email logs data.
+- Fixed: Missing Sendinblue email body WP filter.
+- Fixed: Chart.js library conflicts with other plugins.
+
+= 3.4.0 - 2022-04-27 =
+- Added: New transactional mailer: SendLayer integration.
+- Changed: Improved Mailgun API error message extraction.
+- Changed: Standardized error messages format and improved WP remote request errors extraction.
+- Fixed: Lite plugin uninstall actions clearing plugin options while Pro version is active.
+- Fixed: Hiding unrelated network admin notices on WP Mail SMTP pages.
+
+= 3.3.0 - 2022-02-17 =
+- IMPORTANT: Support for WordPress versions 5.1.x or lower has been discontinued. If you are using one of those versions, you MUST upgrade WordPress before installing or upgrading to WP Mail SMTP v3.3. Failure to do that will disable WP Mail SMTP functionality.
+- Added: PHP 8.1 compatibility.
+- Changed: Updated the list of conflicting plugins (added FluentSMTP and WP HTML Mail).
+- Changed: Improved debug error message for the Other SMTP mailer in Debug Events.
+- Changed: Updated Action Scheduler library to 3.4.0.
+- Changed: Improved Action Scheduler performance.
+- Fixed: PHP deprecated notices in Sendinblue library (PHP 7.4+).
+- Fixed: DB tables row in Site Health Info section is now private.
+- Fixed: Debug Events' screen options visible on general Tools page.
+- Fixed: Screen Options right alignment.
+
+= 3.2.1 - 2021-11-17 =
+- Fixed: PHP 8 compatibility when existing Gmail mailer connection is revoked.
+
+= 3.2.0 - 2021-11-11 =
+- Added: New transactional mailer - SparkPost integration.
+- Added: One-click migration from FluentSMTP plugin.
+- Added: Plugin constants integration in Setup Wizard.
+- Fixed: Early plugin deactivation issue with activity log plugins.
+
+= 3.1.0 - 2021-09-28 =
+- Added: New transactional mailer - Postmark integration.
+- Added: Support for string attachments (added via PHPMailer object).
+- Changed: Improved Email Source detection in Debug Events for WP Core sent emails.
+- Changed: Improved uninstall process. It now removes all plugin DB data and tables.
+- Fixed: Email Source detection in Debug Events for file paths with backslashes.
+- Fixed: Blurry image assets in Weekly Email Summary.
+- Fixed: PHP extension mb_strings not polyfilled correctly.
+- Fixed: Added missing is_email_sent filters for Sendinblue, Mailgun, and Gmail mailers.
+- Fixed: Debug Events double-entry DB save, because of a bug in is_email_sent method for certain mailers.
+
+= 3.0.3 - 2021-08-09 =
+- Fixed: Weekly Summary Email sending when migration code didn't trigger yet.
+
+= 3.0.2 - 2021-08-05 =
+- Fixed: Fatal PHP error on WP version 5.2 and lower (missing wp_timezone function).
+
+= 3.0.1 - 2021-08-05 =
+- Added: Weekly Email Summary - email sending statistics sent to your inbox.
+- Added: Debug Events - logging all email sending errors and debug events.
+- Added: Quick admin area links.
+- Changed: Updated the successful Email Test screen.
+- Changed: Updated Action Scheduler library to 3.2.1.
+- Fixed: WP core admin spinner for the dashboard widget.
+- Fixed: PHP error when objects implementing `__invoke()` method were used as hook callbacks for admin notices.
diff --git a/wp-content/plugins/wp-mail-smtp/src/AbstractConnection.php b/wp-content/plugins/wp-mail-smtp/src/AbstractConnection.php
new file mode 100755
index 00000000..e9d2ec4f
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/src/AbstractConnection.php
@@ -0,0 +1,67 @@
+get_name(),
+ wp_mail_smtp()->get_providers()->get_options( $this->get_mailer_slug(), $this )->get_title()
+ );
+ }
+
+ /**
+ * Get connection mailer slug.
+ *
+ * @since 3.7.0
+ *
+ * @return string
+ */
+ public function get_mailer_slug() {
+
+ return $this->get_options()->get( 'mail', 'mailer' );
+ }
+
+ /**
+ * Get connection mailer object.
+ *
+ * @since 3.7.0
+ *
+ * @return MailerAbstract
+ */
+ public function get_mailer() {
+
+ $phpmailer = wp_mail_smtp()->get_processor()->get_phpmailer();
+
+ return wp_mail_smtp()->get_providers()->get_mailer( $this->get_mailer_slug(), $phpmailer, $this );
+ }
+
+ /**
+ * Whether the connection is primary or not.
+ *
+ * @since 3.7.0
+ *
+ * @return bool
+ */
+ public function is_primary() {
+
+ return false;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/src/Admin/AdminBarMenu.php b/wp-content/plugins/wp-mail-smtp/src/Admin/AdminBarMenu.php
new file mode 100755
index 00000000..501fbb52
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/src/Admin/AdminBarMenu.php
@@ -0,0 +1,164 @@
+hooks();
+ }
+
+ /**
+ * Register hooks.
+ *
+ * @since 2.3.0
+ */
+ public function hooks() {
+
+ add_action( 'wp_enqueue_scripts', [ $this, 'enqueues' ] );
+ add_action( 'admin_enqueue_scripts', [ $this, 'enqueues' ] );
+ add_action( 'admin_bar_menu', [ $this, 'register' ], 999 );
+ }
+
+ /**
+ * Check if current user has access to see admin bar menu.
+ *
+ * @since 2.3.0
+ *
+ * @return bool
+ */
+ public function has_access() {
+
+ $access = false;
+
+ if (
+ is_user_logged_in() &&
+ current_user_can( wp_mail_smtp()->get_capability_manage_options() )
+ ) {
+ $access = true;
+ }
+
+ return apply_filters( 'wp_mail_smtp_admin_adminbarmenu_has_access', $access );
+ }
+
+ /**
+ * Check if new notifications are available.
+ *
+ * @since 2.3.0
+ *
+ * @return bool
+ */
+ public function has_notifications() {
+
+ return wp_mail_smtp()->get_notifications()->get_count();
+ }
+
+ /**
+ * Enqueue styles.
+ *
+ * @since 2.3.0
+ */
+ public function enqueues() {
+
+ if ( ! is_admin_bar_showing() ) {
+ return;
+ }
+
+ if ( ! $this->has_access() ) {
+ return;
+ }
+
+ wp_enqueue_style(
+ 'wp-mail-smtp-admin-bar',
+ wp_mail_smtp()->assets_url . '/css/admin-bar.min.css',
+ [],
+ WPMS_PLUGIN_VER
+ );
+ }
+
+ /**
+ * Register and render admin menu bar.
+ *
+ * @since 2.3.0
+ *
+ * @param \WP_Admin_Bar $wp_admin_bar WordPress Admin Bar object.
+ */
+ public function register( \WP_Admin_Bar $wp_admin_bar ) {
+
+ if (
+ ! $this->has_access() ||
+ (
+ (
+ empty( Debug::get_last() ) ||
+ (bool) Options::init()->get( 'general', 'email_delivery_errors_hidden' )
+ ) &&
+ empty( $this->has_notifications() )
+ )
+ ) {
+ return;
+ }
+
+ $items = apply_filters(
+ 'wp_mail_smtp_admin_adminbarmenu_register',
+ [
+ 'main_menu',
+ ],
+ $wp_admin_bar
+ );
+
+ foreach ( $items as $item ) {
+ $this->{ $item }( $wp_admin_bar );
+
+ do_action( "wp_mail_smtp_admin_adminbarmenu_register_{$item}_after", $wp_admin_bar );
+ }
+ }
+
+ /**
+ * Render primary top-level admin menu bar item.
+ *
+ * @since 2.3.0
+ *
+ * @param \WP_Admin_Bar $wp_admin_bar WordPress Admin Bar object.
+ */
+ public function main_menu( \WP_Admin_Bar $wp_admin_bar ) {
+
+ if (
+ ! empty( Debug::get_last() ) &&
+ ! (bool) Options::init()->get( 'general', 'email_delivery_errors_hidden' )
+ ) {
+ $indicator = ' !';
+ } elseif ( ! empty( $this->has_notifications() ) ) {
+ $count = $this->has_notifications() < 10 ? $this->has_notifications() : '!';
+ $indicator = '
' . $count . '
';
+ }
+
+ if ( ! isset( $indicator ) ) {
+ return;
+ }
+
+ $wp_admin_bar->add_menu(
+ [
+ 'id' => 'wp-mail-smtp-menu',
+ 'title' => 'WP Mail SMTP' . $indicator,
+ 'href' => apply_filters(
+ 'wp_mail_smtp_admin_adminbarmenu_main_menu_href',
+ wp_mail_smtp()->get_admin()->get_admin_page_url()
+ ),
+ ]
+ );
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/src/Admin/Area.php b/wp-content/plugins/wp-mail-smtp/src/Admin/Area.php
new file mode 100755
index 00000000..755d6dda
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/src/Admin/Area.php
@@ -0,0 +1,1587 @@
+hooks();
+ ( new Education() )->hooks();
+ ( new SetupWizard() )->hooks();
+ ( new FlyoutMenu() )->hooks();
+ }
+
+ /**
+ * Display custom notices based on the error/success codes.
+ *
+ * @since 1.0.0
+ */
+ public function display_custom_auth_notices() {
+
+ $error = isset( $_GET['error'] ) ? sanitize_key( $_GET['error'] ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+ $success = isset( $_GET['success'] ) ? sanitize_key( $_GET['success'] ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+
+ if ( empty( $error ) && empty( $success ) ) {
+ return;
+ }
+
+ if ( ! current_user_can( wp_mail_smtp()->get_capability_manage_options() ) ) {
+ return;
+ }
+
+ switch ( $error ) {
+ case 'oauth_invalid_state':
+ WP::add_admin_notice(
+ esc_html__( 'There was an error while processing the authentication request. The state key is invalid. Please try again.', 'wp-mail-smtp' ),
+ WP::ADMIN_NOTICE_ERROR
+ );
+ break;
+
+ case 'google_invalid_nonce':
+ WP::add_admin_notice(
+ esc_html__( 'There was an error while processing the authentication request. The nonce is invalid. Please try again.', 'wp-mail-smtp' ),
+ WP::ADMIN_NOTICE_ERROR
+ );
+ break;
+
+ case 'google_access_denied':
+ WP::add_admin_notice( /* translators: %s - error code, returned by Google API. */
+ sprintf( esc_html__( 'There was an error while processing the authentication request: %s. Please try again.', 'wp-mail-smtp' ), '' . $error . '' ),
+ WP::ADMIN_NOTICE_ERROR
+ );
+ break;
+
+ case 'google_no_code_scope':
+ WP::add_admin_notice(
+ esc_html__( 'There was an error while processing the authentication request. Please try again.', 'wp-mail-smtp' ),
+ WP::ADMIN_NOTICE_ERROR
+ );
+ break;
+
+ case 'google_no_clients':
+ WP::add_admin_notice(
+ esc_html__( 'There was an error while processing the authentication request. Please make sure that you have Client ID and Client Secret both valid and saved.', 'wp-mail-smtp' ),
+ WP::ADMIN_NOTICE_ERROR
+ );
+ break;
+
+ case 'google_unsuccessful_oauth':
+ WP::add_admin_notice(
+ esc_html__( 'There was an error while processing the authentication request.', 'wp-mail-smtp' ),
+ WP::ADMIN_NOTICE_ERROR
+ );
+ break;
+ }
+
+ switch ( $success ) {
+ case 'google_site_linked':
+ WP::add_admin_notice(
+ esc_html__( 'You have successfully linked the current site with your Google API project. Now you can start sending emails through Gmail.', 'wp-mail-smtp' ),
+ WP::ADMIN_NOTICE_SUCCESS
+ );
+ break;
+ }
+ }
+
+ /**
+ * Display notice instructing the user to complete plugin setup.
+ *
+ * @since 1.3.0
+ */
+ public function display_setup_notice() {
+
+ // Bail if we're not on a plugin page.
+ if ( ! $this->is_admin_page( 'general' ) ) {
+ return;
+ }
+
+ $default_options = wp_json_encode( Options::get_defaults() );
+ $current_options = wp_json_encode( Options::init()->get_all() );
+
+ // Check if the current settings are the same as the default settings.
+ if ( $current_options !== $default_options ) {
+ return;
+ }
+
+ // Display notice informing user further action is needed.
+ WP::add_admin_notice(
+ sprintf(
+ wp_kses( /* translators: %s - Mailer anchor link. */
+ __( 'Thanks for using WP Mail SMTP! To complete the plugin setup and start sending emails, please select and configure your Mailer.', 'wp-mail-smtp' ),
+ [
+ 'a' => [
+ 'href' => [],
+ ],
+ 'strong' => [],
+ ]
+ ),
+ wp_mail_smtp()->get_admin()->get_admin_page_url( self::SLUG . '#wp-mail-smtp-setting-row-mailer' )
+ ),
+ WP::ADMIN_NOTICE_INFO
+ );
+ }
+
+ /**
+ * Display notice explaining removal of "Email Test" tab.
+ *
+ * @since 3.9.0
+ */
+ public function display_email_test_tab_removal_notice() {
+
+ // Bail if we aren't on a "Settings" page.
+ if ( ! $this->is_admin_page( self::SLUG ) ) {
+ return;
+ }
+
+ // Bail if the notice has been dismissed.
+ if ( metadata_exists( 'user', get_current_user_id(), 'wp_mail_smtp_email_test_tab_removal_notice_dismissed' ) ) {
+ return;
+ }
+
+ /*
+ * Don't display the notice if the user installed a plugin with a new "Email Test"
+ * location (starting from v3.9.0) and is not aware of the old one. Also, don't display
+ * the notice if the `wp_mail_smtp_initial_version` option is not set (it can happen if
+ * the plugin was activated network wise in the multisite installation and plugin
+ * activation hook was not performed on the subsite level).
+ */
+ if ( version_compare( get_option( 'wp_mail_smtp_initial_version', '3.9.0' ), '3.9.0', '>=' ) ) {
+ return;
+ }
+
+ WP::add_admin_notice(
+ sprintf(
+ wp_kses(
+ /* translators: %s: Tools page URL. */
+ __( 'The Email Test tab was moved to WP Mail SMTP > Tools.', 'wp-mail-smtp' ),
+ [ 'a' => [ 'href' => [] ] ]
+ ),
+ $this->get_admin_page_url( self::SLUG . '-tools' )
+ ),
+ implode( ' ', [ WP::ADMIN_NOTICE_INFO, 'email_test_tab_removal_notice' ] )
+ );
+ }
+
+ /**
+ * Get menu item position.
+ *
+ * @since 2.8.0
+ *
+ * @return int
+ */
+ public function get_menu_item_position() {
+
+ /**
+ * Filters menu item position.
+ *
+ * @since 2.8.0
+ *
+ * @param int $position Position number.
+ */
+ return apply_filters( 'wp_mail_smtp_admin_area_get_menu_item_position', 98 );
+ }
+
+ /**
+ * Add admin area menu item.
+ *
+ * @since 1.0.0
+ * @since 1.5.0 Moved the menu to the top level. Added several more pages.
+ */
+ public function add_admin_options_page() {
+
+ // Options pages access capability.
+ $access_capability = wp_mail_smtp()->get_capability_manage_options();
+
+ $this->hook = add_menu_page(
+ esc_html__( 'WP Mail SMTP', 'wp-mail-smtp' ),
+ esc_html__( 'WP Mail SMTP', 'wp-mail-smtp' ),
+ $access_capability,
+ self::SLUG,
+ [ $this, 'display' ],
+ 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiM5ZWEzYTgiIHdpZHRoPSI2NCIgaGVpZ2h0PSI2NCIgdmlld0JveD0iMCAwIDQzIDM0Ij48cGF0aCBkPSJNMC4wMDcsMy41ODVWMjAuNDIxcTAsMy41ODYsMy43NTEsMy41ODVMMjAsMjRWMTlIMzBWMTQuMDE0bDAuOTkxLTFMMzQsMTNWMy41ODVRMzQsMCwzMC4yNDksMEgzLjc1OFEwLjAwNywwLC4wMDcsMy41ODVoMFpNMy41MjQsNi4xNTdhMS40OSwxLjQ5LDAsMCwxLS41MDgtMC45MzUsMS41ODEsMS41ODEsMCwwLDEsLjI3NC0xLjIwOCwxLjQ0OSwxLjQ0OSwwLDAsMSwxLjA5NC0uNjYzLDEuNzU2LDEuNzU2LDAsMCwxLDEuMjUuMzEybDExLjQwOSw3LjcxNkwyOC4zNzQsMy42NjNhMS45NiwxLjk2LDAsMCwxLDEuMjg5LS4zMTIsMS41NDYsMS41NDYsMCwwLDEsMS4wOTQuNjYzLDEuNCwxLjQsMCwwLDEsLjI3MywxLjIwOCwxLjY3LDEuNjcsMCwwLDEtLjU0Ny45MzVMMTcuMDQzLDE3LjIyNVoiLz48cGF0aCBkPSJNMjIsMjhIMzJsLTAuMDA5LDQuNjI0YTEuMTI2LDEuMTI2LDAsMCwwLDEuOTIyLjhsOC4yNS04LjIzNmExLjEyNiwxLjEyNiwwLDAsMCwwLTEuNTk0bC04LjI1LTguMjQxYTEuMTI2LDEuMTI2LDAsMCwwLTEuOTIyLjh2NC44NjZMMjIsMjF2N1oiLz48L3N2Zz4=',
+ $this->get_menu_item_position()
+ );
+
+ add_submenu_page(
+ self::SLUG,
+ $this->get_current_tab_title() . ' ‹ ' . \esc_html__( 'Settings', 'wp-mail-smtp' ),
+ esc_html__( 'Settings', 'wp-mail-smtp' ),
+ $access_capability,
+ self::SLUG,
+ [ $this, 'display' ]
+ );
+
+ add_submenu_page(
+ self::SLUG,
+ esc_html__( 'Email Log', 'wp-mail-smtp' ),
+ esc_html__( 'Email Log', 'wp-mail-smtp' ),
+ $this->get_logs_access_capability(),
+ self::SLUG . '-logs',
+ [ $this, 'display' ]
+ );
+
+ foreach ( $this->get_parent_pages() as $page ) {
+ add_submenu_page(
+ self::SLUG,
+ esc_html( $page->get_title() ),
+ esc_html( $page->get_label() ),
+ $access_capability,
+ self::SLUG . '-' . $page->get_slug(),
+ [ $this, 'display' ]
+ );
+ }
+
+ if ( ! wp_mail_smtp()->is_pro() ) {
+ add_submenu_page(
+ self::SLUG,
+ esc_html__( 'Upgrade to Pro', 'wp-mail-smtp' ),
+ esc_html__( 'Upgrade to Pro', 'wp-mail-smtp' ),
+ $access_capability,
+ // phpcs:ignore WordPress.Arrays.ArrayDeclarationSpacing.AssociativeArrayFound
+ esc_url( wp_mail_smtp()->get_upgrade_link( [ 'medium' => 'admin-menu', 'content' => 'Upgrade to Pro' ] ) )
+ );
+ }
+ }
+
+ /**
+ * Add network admin settings page for the WPMS product education.
+ *
+ * @since 2.5.0
+ */
+ public function add_wpms_network_wide_setting_product_education_page() {
+
+ add_menu_page(
+ esc_html__( 'WP Mail SMTP', 'wp-mail-smtp' ),
+ esc_html__( 'WP Mail SMTP', 'wp-mail-smtp' ),
+ wp_mail_smtp()->get_capability_manage_options(),
+ self::SLUG,
+ [ $this, 'display_network_product_education_page' ],
+ 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiM5ZWEzYTgiIHdpZHRoPSI2NCIgaGVpZ2h0PSI2NCIgdmlld0JveD0iMCAwIDQzIDM0Ij48cGF0aCBkPSJNMC4wMDcsMy41ODVWMjAuNDIxcTAsMy41ODYsMy43NTEsMy41ODVMMjAsMjRWMTlIMzBWMTQuMDE0bDAuOTkxLTFMMzQsMTNWMy41ODVRMzQsMCwzMC4yNDksMEgzLjc1OFEwLjAwNywwLC4wMDcsMy41ODVoMFpNMy41MjQsNi4xNTdhMS40OSwxLjQ5LDAsMCwxLS41MDgtMC45MzUsMS41ODEsMS41ODEsMCwwLDEsLjI3NC0xLjIwOCwxLjQ0OSwxLjQ0OSwwLDAsMSwxLjA5NC0uNjYzLDEuNzU2LDEuNzU2LDAsMCwxLDEuMjUuMzEybDExLjQwOSw3LjcxNkwyOC4zNzQsMy42NjNhMS45NiwxLjk2LDAsMCwxLDEuMjg5LS4zMTIsMS41NDYsMS41NDYsMCwwLDEsMS4wOTQuNjYzLDEuNCwxLjQsMCwwLDEsLjI3MywxLjIwOCwxLjY3LDEuNjcsMCwwLDEtLjU0Ny45MzVMMTcuMDQzLDE3LjIyNVoiLz48cGF0aCBkPSJNMjIsMjhIMzJsLTAuMDA5LDQuNjI0YTEuMTI2LDEuMTI2LDAsMCwwLDEuOTIyLjhsOC4yNS04LjIzNmExLjEyNiwxLjEyNiwwLDAsMCwwLTEuNTk0bC04LjI1LTguMjQxYTEuMTI2LDEuMTI2LDAsMCwwLTEuOTIyLjh2NC44NjZMMjIsMjF2N1oiLz48L3N2Zz4=',
+ $this->get_menu_item_position()
+ );
+ }
+
+ /**
+ * HTML output for the network admin settings page (for the WPMS product education).
+ *
+ * @since 2.5.0
+ */
+ public function display_network_product_education_page() {
+
+ // Skip if not on multisite and not on network admin site.
+ if ( ! is_multisite() || ! is_network_admin() ) {
+ return;
+ }
+
+ ?>
+
+
+
+ [
+ 'path' => 'optinmonster/optin-monster-wp-api.php',
+ 'icon' => wp_mail_smtp()->assets_url . '/images/about/plugin-om.png',
+ 'name' => esc_html__( 'OptinMonster', 'wp-mail-smtp' ),
+ 'desc' => esc_html__( 'Instantly get more subscribers, leads, and sales with the #1 conversion optimization toolkit. Create high converting popups, announcement bars, spin a wheel, and more with smart targeting and personalization.', 'wp-mail-smtp' ),
+ 'url' => 'https://downloads.wordpress.org/plugin/optinmonster.zip',
+ ],
+ 'wpforms' => [
+ 'path' => 'wpforms-lite/wpforms.php',
+ 'icon' => wp_mail_smtp()->assets_url . '/images/about/plugin-wpf.png',
+ 'name' => esc_html__( 'WPForms', 'wp-mail-smtp' ),
+ 'desc' => esc_html__( 'The best drag & drop WordPress form builder. Easily create beautiful contact forms, surveys, payment forms, and more with our 600+ form templates. Trusted by over 5 million websites as the best forms plugin.', 'wp-mail-smtp' ),
+ 'url' => 'https://downloads.wordpress.org/plugin/wpforms-lite.zip',
+ 'pro' => [
+ 'path' => 'wpforms/wpforms.php',
+ 'icon' => wp_mail_smtp()->assets_url . '/images/about/plugin-wpf.png',
+ 'name' => esc_html__( 'WPForms Pro', 'wp-mail-smtp' ),
+ 'desc' => esc_html__( 'The best drag & drop WordPress form builder. Easily create beautiful contact forms, surveys, payment forms, and more with our 600+ form templates. Trusted by over 5 million websites as the best forms plugin.', 'wp-mail-smtp' ),
+ 'url' => 'https://wpforms.com/?utm_source=WordPress&utm_medium=about&utm_campaign=smtp',
+ ],
+ ],
+ 'mi' => [
+ 'path' => 'google-analytics-for-wordpress/googleanalytics.php',
+ 'icon' => wp_mail_smtp()->assets_url . '/images/about/plugin-mi.png',
+ 'name' => esc_html__( 'MonsterInsights', 'wp-mail-smtp' ),
+ 'desc' => esc_html__( 'The leading WordPress analytics plugin that shows you how people find and use your website, so you can make data driven decisions to grow your business. Properly set up Google Analytics without writing code.', 'wp-mail-smtp' ),
+ 'url' => 'https://downloads.wordpress.org/plugin/google-analytics-for-wordpress.zip',
+ 'pro' => [
+ 'path' => 'google-analytics-premium/googleanalytics-premium.php',
+ 'icon' => wp_mail_smtp()->assets_url . '/images/about/plugin-mi.png',
+ 'name' => esc_html__( 'MonsterInsights Pro', 'wp-mail-smtp' ),
+ 'desc' => esc_html__( 'The leading WordPress analytics plugin that shows you how people find and use your website, so you can make data driven decisions to grow your business. Properly set up Google Analytics without writing code.', 'wp-mail-smtp' ),
+ 'url' => 'https://www.monsterinsights.com/?utm_source=WordPress&utm_medium=about&utm_campaign=smtp',
+ ],
+ ],
+ 'aioseo' => [
+ 'path' => 'all-in-one-seo-pack/all_in_one_seo_pack.php',
+ 'icon' => wp_mail_smtp()->assets_url . '/images/about/plugin-aioseo.png',
+ 'name' => esc_html__( 'AIOSEO', 'wp-mail-smtp' ),
+ 'desc' => esc_html__( 'The original WordPress SEO plugin and toolkit that improves your websiteās search rankings. Comes with all the SEO features like Local SEO, WooCommerce SEO, sitemaps, SEO optimizer, schema, and more.', 'wp-mail-smtp' ),
+ 'url' => 'https://downloads.wordpress.org/plugin/all-in-one-seo-pack.zip',
+ 'pro' => [
+ 'path' => 'all-in-one-seo-pack-pro/all_in_one_seo_pack.php',
+ 'icon' => wp_mail_smtp()->assets_url . '/images/about/plugin-aioseo.png',
+ 'name' => esc_html__( 'AIOSEO', 'wp-mail-smtp' ),
+ 'desc' => esc_html__( 'The original WordPress SEO plugin and toolkit that improves your websiteās search rankings. Comes with all the SEO features like Local SEO, WooCommerce SEO, sitemaps, SEO optimizer, schema, and more.', 'wp-mail-smtp' ),
+ 'url' => 'https://aioseo.com/?utm_source=WordPress&utm_medium=about&utm_campaign=smtp',
+ ],
+ ],
+ 'seedprod' => [
+ 'path' => 'coming-soon/coming-soon.php',
+ 'icon' => wp_mail_smtp()->assets_url . '/images/about/plugin-seedprod.png',
+ 'name' => esc_html__( 'SeedProd', 'wp-mail-smtp' ),
+ 'desc' => esc_html__( 'The fastest drag & drop landing page builder for WordPress. Create custom landing pages without writing code, connect them with your CRM, collect subscribers, and grow your audience. Trusted by 1 million sites.', 'wp-mail-smtp' ),
+ 'url' => 'https://downloads.wordpress.org/plugin/coming-soon.zip',
+ 'pro' => [
+ 'path' => 'seedprod-coming-soon-pro-5/seedprod-coming-soon-pro-5.php',
+ 'icon' => wp_mail_smtp()->assets_url . '/images/about/plugin-seedprod.png',
+ 'name' => esc_html__( 'SeedProd', 'wp-mail-smtp' ),
+ 'desc' => esc_html__( 'The fastest drag & drop landing page builder for WordPress. Create custom landing pages without writing code, connect them with your CRM, collect subscribers, and grow your audience. Trusted by 1 million sites.', 'wp-mail-smtp' ),
+ 'url' => 'https://www.seedprod.com/?utm_source=WordPress&utm_medium=about&utm_campaign=smtp',
+ ],
+ ],
+ 'rafflepress' => [
+ 'path' => 'rafflepress/rafflepress.php',
+ 'icon' => wp_mail_smtp()->assets_url . '/images/about/plugin-rp.png',
+ 'name' => esc_html__( 'RafflePress', 'wp-mail-smtp' ),
+ 'desc' => esc_html__( 'Turn your website visitors into brand ambassadors! Easily grow your email list, website traffic, and social media followers with the most powerful giveaways & contests plugin for WordPress.', 'wp-mail-smtp' ),
+ 'url' => 'https://downloads.wordpress.org/plugin/rafflepress.zip',
+ 'pro' => [
+ 'path' => 'rafflepress-pro/rafflepress-pro.php',
+ 'icon' => wp_mail_smtp()->assets_url . '/images/about/plugin-rp.png',
+ 'name' => esc_html__( 'RafflePress Pro', 'wp-mail-smtp' ),
+ 'desc' => esc_html__( 'Turn your website visitors into brand ambassadors! Easily grow your email list, website traffic, and social media followers with the most powerful giveaways & contests plugin for WordPress.', 'wp-mail-smtp' ),
+ 'url' => 'https://rafflepress.com/pricing/?utm_source=WordPress&utm_medium=about&utm_campaign=smtp',
+ ],
+ ],
+ 'pushengage' => [
+ 'path' => 'pushengage/main.php',
+ 'icon' => wp_mail_smtp()->assets_url . '/images/about/plugin-pushengage.png',
+ 'name' => esc_html__( 'PushEngage', 'wp-mail-smtp' ),
+ 'desc' => esc_html__( 'Connect with your visitors after they leave your website with the leading web push notification software. Over 10,000+ businesses worldwide use PushEngage to send 15 billion notifications each month.', 'wp-mail-smtp' ),
+ 'url' => 'https://downloads.wordpress.org/plugin/pushengage.zip',
+ ],
+ 'smash-balloon-instagram-feeds' => [
+ 'path' => 'instagram-feed/instagram-feed.php',
+ 'icon' => wp_mail_smtp()->assets_url . '/images/about/plugin-smash-balloon-instagram-feeds.png',
+ 'name' => esc_html__( 'Smash Balloon Instagram Feeds', 'wp-mail-smtp' ),
+ 'desc' => esc_html__( 'Easily display Instagram content on your WordPress site without writing any code. Comes with multiple templates, ability to show content from multiple accounts, hashtags, and more. Trusted by 1 million websites.', 'wp-mail-smtp' ),
+ 'url' => 'https://downloads.wordpress.org/plugin/instagram-feed.zip',
+ 'pro' => [
+ 'path' => 'instagram-feed-pro/instagram-feed.php',
+ 'icon' => wp_mail_smtp()->assets_url . '/images/about/plugin-smash-balloon-instagram-feeds.png',
+ 'name' => esc_html__( 'Smash Balloon Instagram Feeds', 'wp-mail-smtp' ),
+ 'desc' => esc_html__( 'Easily display Instagram content on your WordPress site without writing any code. Comes with multiple templates, ability to show content from multiple accounts, hashtags, and more. Trusted by 1 million websites.', 'wp-mail-smtp' ),
+ 'url' => 'https://smashballoon.com/instagram-feed/?utm_source=WordPress&utm_medium=about&utm_campaign=smtp',
+ ],
+ ],
+ 'smash-balloon-facebook-feeds' => [
+ 'path' => 'custom-facebook-feed/custom-facebook-feed.php',
+ 'icon' => wp_mail_smtp()->assets_url . '/images/about/plugin-smash-balloon-facebook-feeds.png',
+ 'name' => esc_html__( 'Smash Balloon Facebook Feeds', 'wp-mail-smtp' ),
+ 'desc' => esc_html__( 'Easily display Facebook content on your WordPress site without writing any code. Comes with multiple templates, ability to embed albums, group content, reviews, live videos, comments, and reactions.', 'wp-mail-smtp' ),
+ 'url' => 'https://downloads.wordpress.org/plugin/custom-facebook-feed.zip',
+ 'pro' => [
+ 'path' => 'custom-facebook-feed-pro/custom-facebook-feed.php',
+ 'icon' => wp_mail_smtp()->assets_url . '/images/about/plugin-smash-balloon-facebook-feeds.png',
+ 'name' => esc_html__( 'Smash Balloon Facebook Feeds', 'wp-mail-smtp' ),
+ 'desc' => esc_html__( 'Easily display Facebook content on your WordPress site without writing any code. Comes with multiple templates, ability to embed albums, group content, reviews, live videos, comments, and reactions.', 'wp-mail-smtp' ),
+ 'url' => 'https://smashballoon.com/custom-facebook-feed/?utm_source=WordPress&utm_medium=about&utm_campaign=smtp',
+ ],
+ ],
+ 'smash-balloon-youtube-feeds' => [
+ 'path' => 'feeds-for-youtube/youtube-feed.php',
+ 'icon' => wp_mail_smtp()->assets_url . '/images/about/plugin-smash-balloon-youtube-feeds.png',
+ 'name' => esc_html__( 'Smash Balloon YouTube Feeds', 'wp-mail-smtp' ),
+ 'desc' => esc_html__( 'Easily display YouTube videos on your WordPress site without writing any code. Comes with multiple layouts, ability to embed live streams, video filtering, ability to combine multiple channel videos, and more.', 'wp-mail-smtp' ),
+ 'url' => 'https://downloads.wordpress.org/plugin/feeds-for-youtube.zip',
+ 'pro' => [
+ 'path' => 'youtube-feed-pro/youtube-feed.php',
+ 'icon' => wp_mail_smtp()->assets_url . '/images/about/plugin-smash-balloon-youtube-feeds.png',
+ 'name' => esc_html__( 'Smash Balloon YouTube Feeds', 'wp-mail-smtp' ),
+ 'desc' => esc_html__( 'Easily display YouTube videos on your WordPress site without writing any code. Comes with multiple layouts, ability to embed live streams, video filtering, ability to combine multiple channel videos, and more.', 'wp-mail-smtp' ),
+ 'url' => 'https://smashballoon.com/youtube-feed/?utm_source=WordPress&utm_medium=about&utm_campaign=smtp',
+ ],
+ ],
+ 'smash-balloon-twitter-feeds' => [
+ 'path' => 'custom-twitter-feeds/custom-twitter-feed.php',
+ 'icon' => wp_mail_smtp()->assets_url . '/images/about/plugin-smash-balloon-twitter-feeds.png',
+ 'name' => esc_html__( 'Smash Balloon Twitter Feeds', 'wp-mail-smtp' ),
+ 'desc' => esc_html__( 'Easily display Twitter content in WordPress without writing any code. Comes with multiple layouts, ability to combine multiple Twitter feeds, Twitter card support, tweet moderation, and more.', 'wp-mail-smtp' ),
+ 'url' => 'https://downloads.wordpress.org/plugin/custom-twitter-feeds.zip',
+ 'pro' => [
+ 'path' => 'custom-twitter-feeds-pro/custom-twitter-feed.php',
+ 'icon' => wp_mail_smtp()->assets_url . '/images/about/plugin-smash-balloon-twitter-feeds.png',
+ 'name' => esc_html__( 'Smash Balloon Twitter Feeds', 'wp-mail-smtp' ),
+ 'desc' => esc_html__( 'Easily display Twitter content in WordPress without writing any code. Comes with multiple layouts, ability to combine multiple Twitter feeds, Twitter card support, tweet moderation, and more.', 'wp-mail-smtp' ),
+ 'url' => 'https://smashballoon.com/custom-twitter-feeds/?utm_source=WordPress&utm_medium=about&utm_campaign=smtp',
+ ],
+ ],
+ 'trustpulse' => [
+ 'path' => 'trustpulse-api/trustpulse.php',
+ 'icon' => wp_mail_smtp()->assets_url . '/images/about/plugin-trustpulse.png',
+ 'name' => esc_html__( 'TrustPulse', 'wp-mail-smtp' ),
+ 'desc' => esc_html__( 'Boost your sales and conversions by up to 15% with real-time social proof notifications. TrustPulse helps you show live user activity and purchases to help convince other users to purchase.', 'wp-mail-smtp' ),
+ 'url' => 'https://downloads.wordpress.org/plugin/trustpulse-api.zip',
+ ],
+ 'searchwp' => [
+ 'path' => '',
+ 'icon' => wp_mail_smtp()->assets_url . '/images/about/searchwp.png',
+ 'name' => esc_html__( 'SearchWP', 'wp-mail-smtp' ),
+ 'desc' => esc_html__( 'The most advanced WordPress search plugin. Customize your WordPress search algorithm, reorder search results, track search metrics, and everything you need to leverage search to grow your business.', 'wp-mail-smtp' ),
+ 'url' => 'https://searchwp.com/?utm_source=WordPress&utm_medium=about&utm_campaign=smtp',
+ 'pro' => [
+ 'path' => 'searchwp/index.php',
+ 'icon' => wp_mail_smtp()->assets_url . '/images/about/searchwp.png',
+ 'name' => esc_html__( 'SearchWP', 'wp-mail-smtp' ),
+ 'desc' => esc_html__( 'The most advanced WordPress search plugin. Customize your WordPress search algorithm, reorder search results, track search metrics, and everything you need to leverage search to grow your business.', 'wp-mail-smtp' ),
+ 'url' => 'https://searchwp.com/?utm_source=WordPress&utm_medium=about&utm_campaign=smtp',
+ ],
+ ],
+ 'affiliatewp' => [
+ 'path' => '',
+ 'icon' => wp_mail_smtp()->assets_url . '/images/about/affiliatewp.png',
+ 'name' => esc_html__( 'AffiliateWP', 'wp-mail-smtp' ),
+ 'desc' => esc_html__( 'The #1 affiliate management plugin for WordPress. Easily create an affiliate program for your eCommerce store or membership site within minutes and start growing your sales with the power of referral marketing.', 'wp-mail-smtp' ),
+ 'url' => 'https://affiliatewp.com/?utm_source=WordPress&utm_medium=about&utm_campaign=smtp',
+ 'pro' => [
+ 'path' => 'affiliate-wp/affiliate-wp.php',
+ 'icon' => wp_mail_smtp()->assets_url . '/images/about/affiliatewp.png',
+ 'name' => esc_html__( 'AffiliateWP', 'wp-mail-smtp' ),
+ 'desc' => esc_html__( 'The #1 affiliate management plugin for WordPress. Easily create an affiliate program for your eCommerce store or membership site within minutes and start growing your sales with the power of referral marketing.', 'wp-mail-smtp' ),
+ 'url' => 'https://affiliatewp.com/?utm_source=WordPress&utm_medium=about&utm_campaign=smtp',
+ ],
+ ],
+ 'wp-simple-pay' => [
+ 'path' => 'stripe/stripe-checkout.php',
+ 'icon' => wp_mail_smtp()->assets_url . '/images/about/wp-simple-pay.png',
+ 'name' => esc_html__( 'WP Simple Pay', 'wp-mail-smtp' ),
+ 'desc' => esc_html__( 'The #1 Stripe payments plugin for WordPress. Start accepting one-time and recurring payments on your WordPress site without setting up a shopping cart. No code required.', 'wp-mail-smtp' ),
+ 'url' => 'https://downloads.wordpress.org/plugin/stripe.zip',
+ 'pro' => [
+ 'path' => 'wp-simple-pay-pro-3/simple-pay.php',
+ 'icon' => wp_mail_smtp()->assets_url . '/images/about/wp-simple-pay.png',
+ 'name' => esc_html__( 'WP Simple Pay Pro', 'wp-mail-smtp' ),
+ 'desc' => esc_html__( 'The #1 Stripe payments plugin for WordPress. Start accepting one-time and recurring payments on your WordPress site without setting up a shopping cart. No code required.', 'wp-mail-smtp' ),
+ 'url' => 'https://wpsimplepay.com/?utm_source=WordPress&utm_medium=about&utm_campaign=smtp',
+ ],
+ ],
+ 'easy-digital-downloads' => [
+ 'path' => 'easy-digital-downloads/easy-digital-downloads.php',
+ 'icon' => wp_mail_smtp()->assets_url . '/images/about/edd.png',
+ 'name' => esc_html__( 'Easy Digital Downloads', 'wp-mail-smtp' ),
+ 'desc' => esc_html__( 'The best WordPress eCommerce plugin for selling digital downloads. Start selling eBooks, software, music, digital art, and more within minutes. Accept payments, manage subscriptions, advanced access control, and more.', 'wp-mail-smtp' ),
+ 'url' => 'https://downloads.wordpress.org/plugin/easy-digital-downloads.zip',
+ ],
+ 'sugar-calendar' => [
+ 'path' => 'sugar-calendar-lite/sugar-calendar-lite.php',
+ 'icon' => wp_mail_smtp()->assets_url . '/images/about/sugar-calendar.png',
+ 'name' => esc_html__( 'Sugar Calendar Lite', 'wp-mail-smtp' ),
+ 'desc' => esc_html__( 'A simple & powerful event calendar plugin for WordPress that comes with all the event management features including payments, scheduling, timezones, ticketing, recurring events, and more.', 'wp-mail-smtp' ),
+ 'url' => 'https://downloads.wordpress.org/plugin/sugar-calendar-lite.zip',
+ 'pro' => [
+ 'path' => 'sugar-calendar/sugar-calendar.php',
+ 'icon' => wp_mail_smtp()->assets_url . '/images/about/sugar-calendar.png',
+ 'name' => esc_html__( 'Sugar Calendar', 'wp-mail-smtp' ),
+ 'desc' => esc_html__( 'A simple & powerful event calendar plugin for WordPress that comes with all the event management features including payments, scheduling, timezones, ticketing, recurring events, and more.', 'wp-mail-smtp' ),
+ 'url' => 'https://sugarcalendar.com/?utm_source=WordPress&utm_medium=about&utm_campaign=smtp',
+ ],
+ ],
+ 'wp-charitable' => [
+ 'path' => 'charitable/charitable.php',
+ 'icon' => wp_mail_smtp()->assets_url . '/images/about/plugin-charitable.png',
+ 'name' => esc_html__( 'Charitable', 'wp-mail-smtp' ),
+ 'desc' => esc_html__( 'Top-rated WordPress donation and fundraising plugin. Over 10,000+ non-profit organizations and website owners use Charitable to create fundraising campaigns and raise more money online.', 'wp-mail-smtp' ),
+ 'url' => 'https://downloads.wordpress.org/plugin/charitable.zip',
+ ],
+ 'wpcode' => [
+ 'path' => 'insert-headers-and-footers/ihaf.php',
+ 'icon' => wp_mail_smtp()->assets_url . '/images/about/plugin-wpcode.png',
+ 'name' => esc_html__( 'WPCode Lite', 'wp-mail-smtp' ),
+ 'desc' => esc_html__( 'Future proof your WordPress customizations with the most popular code snippet management plugin for WordPress. Trusted by over 1,500,000+ websites for easily adding code to WordPress right from the admin area.', 'wp-mail-smtp' ),
+ 'url' => 'https://downloads.wordpress.org/plugin/insert-headers-and-footers.zip',
+ 'pro' => [
+ 'path' => 'wpcode-premium/wpcode.php',
+ 'icon' => wp_mail_smtp()->assets_url . '/images/about/plugin-wpcode.png',
+ 'name' => esc_html__( 'WPCode Pro', 'wp-mail-smtp' ),
+ 'desc' => esc_html__( 'Future proof your WordPress customizations with the most popular code snippet management plugin for WordPress. Trusted by over 1,500,000+ websites for easily adding code to WordPress right from the admin area.', 'wp-mail-smtp' ),
+ 'url' => 'https://wpcode.com/?utm_source=WordPress&utm_medium=about&utm_campaign=smtp',
+ ],
+ ],
+ 'duplicator' => [
+ 'path' => 'duplicator/duplicator.php',
+ 'icon' => wp_mail_smtp()->assets_url . '/images/about/duplicator-icon-large.png',
+ 'name' => esc_html__( 'Duplicator', 'wp-mail-smtp' ),
+ 'desc' => esc_html__( 'Leading WordPress backup & site migration plugin. Over 1,500,000+ smart website owners use Duplicator to make reliable and secure WordPress backups to protect their websites. It also makes website migration really easy.', 'wp-mail-smtp' ),
+ 'url' => 'https://downloads.wordpress.org/plugin/duplicator.zip',
+ 'pro' => [
+ 'path' => 'duplicator-pro/duplicator-pro.php',
+ 'icon' => wp_mail_smtp()->assets_url . '/images/about/duplicator-icon-large.png',
+ 'name' => esc_html__( 'Duplicator Pro', 'wp-mail-smtp' ),
+ 'desc' => esc_html__( 'Leading WordPress backup & site migration plugin. Over 1,500,000+ smart website owners use Duplicator to make reliable and secure WordPress backups to protect their websites. It also makes website migration really easy.', 'wp-mail-smtp' ),
+ 'url' => 'https://duplicator.com/?utm_source=WordPress&utm_medium=about&utm_campaign=smtp',
+ ],
+ ],
+ ];
+
+ return $data;
+ }
+
+ /**
+ * Active the given plugin.
+ *
+ * @since 2.9.0
+ */
+ public static function ajax_plugin_activate() {
+
+ // Run a security check.
+ check_ajax_referer( 'wp-mail-smtp-about', 'nonce' );
+
+ $error = esc_html__( 'Could not activate the plugin. Please activate it from the Plugins page.', 'wp-mail-smtp' );
+
+ // Check for permissions.
+ if ( ! current_user_can( 'activate_plugins' ) ) {
+ wp_send_json_error( $error );
+ }
+
+ if ( empty( $_POST['plugin'] ) ) {
+ wp_send_json_error( $error );
+ }
+
+ $plugin_slug = sanitize_text_field( wp_unslash( $_POST['plugin'] ) );
+
+ $whitelisted_plugins = [];
+
+ foreach ( self::get_am_plugins() as $item ) {
+ if ( ! empty( $item['path'] ) ) {
+ $whitelisted_plugins[] = $item['path'];
+ }
+
+ if ( ! empty( $item['pro']['path'] ) ) {
+ $whitelisted_plugins[] = $item['pro']['path'];
+ }
+ }
+
+ if ( ! in_array( $plugin_slug, $whitelisted_plugins, true ) ) {
+ wp_send_json_error( esc_html__( 'Could not activate the plugin. Plugin is not whitelisted.', 'wp-mail-smtp' ) );
+ }
+
+ $activate = activate_plugins( $plugin_slug );
+
+ if ( ! is_wp_error( $activate ) ) {
+ wp_send_json_success( esc_html__( 'Plugin activated.', 'wp-mail-smtp' ) );
+ }
+
+ wp_send_json_error( $error );
+ }
+
+ /**
+ * Install & activate the given plugin.
+ *
+ * @since 2.9.0
+ */
+ public static function ajax_plugin_install() { // phpcs:ignore:Generic.Metrics.CyclomaticComplexity.TooHigh
+
+ // Run a security check.
+ check_ajax_referer( 'wp-mail-smtp-about', 'nonce' );
+
+ $error = esc_html__( 'Could not install the plugin.', 'wp-mail-smtp' );
+
+ // Check for permissions.
+ if ( ! current_user_can( 'install_plugins' ) ) {
+ wp_send_json_error( $error );
+ }
+
+ if ( empty( $_POST['plugin'] ) ) {
+ wp_send_json_error();
+ }
+
+ $plugin_url = esc_url_raw( wp_unslash( $_POST['plugin'] ) );
+
+ if ( ! in_array( $plugin_url, wp_list_pluck( array_values( self::get_am_plugins() ), 'url' ) , true ) ) {
+ wp_send_json_error( esc_html__( 'Could not install the plugin. Plugin is not whitelisted.', 'wp-mail-smtp' ) );
+ }
+
+ // Set the current screen to avoid undefined notices.
+ set_current_screen( 'wp-mail-smtp_page_wp-mail-smtp-about' );
+
+ // Prepare variables.
+ $url = esc_url_raw(
+ add_query_arg(
+ [
+ 'page' => 'wp-mail-smtp-about',
+ ],
+ admin_url( 'admin.php' )
+ )
+ );
+
+ /*
+ * The `request_filesystem_credentials` function will output a credentials form in case of failure.
+ * We don't want that, since it will break AJAX response. So just hide output with a buffer.
+ */
+ ob_start();
+ // phpcs:ignore WPForms.Formatting.EmptyLineAfterAssigmentVariables.AddEmptyLine
+ $creds = request_filesystem_credentials( $url, '', false, false, null );
+ ob_end_clean();
+
+ // Check for file system permissions.
+ if ( false === $creds ) {
+ wp_send_json_error( $error );
+ }
+
+ if ( ! WP_Filesystem( $creds ) ) {
+ wp_send_json_error( $error );
+ }
+
+ // Do not allow WordPress to search/download translations, as this will break JS output.
+ remove_action( 'upgrader_process_complete', [ 'Language_Pack_Upgrader', 'async_upgrade' ], 20 );
+
+ // Import the plugin upgrader.
+ Helpers::include_plugin_upgrader();
+
+ // Create the plugin upgrader with our custom skin.
+ $installer = new Plugin_Upgrader( new PluginsInstallSkin() );
+
+ // Error check.
+ if ( ! method_exists( $installer, 'install' ) ) {
+ wp_send_json_error( $error );
+ }
+
+ $installer->install( $plugin_url );
+
+ // Flush the cache and return the newly installed plugin basename.
+ wp_cache_flush();
+
+ if ( $installer->plugin_info() ) {
+
+ $plugin_basename = $installer->plugin_info();
+
+ if ( $plugin_basename === 'wpforms-lite/wpforms.php' ) {
+ add_option( 'wpforms_installation_source', 'wp-mail-smtp-about-us' );
+ }
+
+ // Activate the plugin silently.
+ $activated = activate_plugin( $plugin_basename );
+
+ if ( ! is_wp_error( $activated ) ) {
+ wp_send_json_success(
+ [
+ 'msg' => esc_html__( 'Plugin installed & activated.', 'wp-mail-smtp' ),
+ 'is_activated' => true,
+ 'basename' => $plugin_basename,
+ ]
+ );
+ } else {
+ wp_send_json_success(
+ [
+ 'msg' => esc_html__( 'Plugin installed.', 'wp-mail-smtp' ),
+ 'is_activated' => false,
+ 'basename' => $plugin_basename,
+ ]
+ );
+ }
+ }
+
+ wp_send_json_error( $error );
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/src/Admin/Pages/ActionSchedulerTab.php b/wp-content/plugins/wp-mail-smtp/src/Admin/Pages/ActionSchedulerTab.php
new file mode 100755
index 00000000..2a5a0ebd
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/src/Admin/Pages/ActionSchedulerTab.php
@@ -0,0 +1,157 @@
+get_label();
+ }
+
+ /**
+ * URL to a tab.
+ *
+ * @since 2.9.0
+ *
+ * @return string
+ */
+ public function get_link() {
+
+ return add_query_arg( [ 's' => 'wp_mail_smtp' ], parent::get_link() );
+ }
+
+ /**
+ * Register hooks.
+ *
+ * @since 2.9.0
+ */
+ public function hooks() {
+
+ add_action( 'current_screen', [ $this, 'init' ], 20 );
+ }
+
+ /**
+ * Init.
+ *
+ * @since 2.9.0
+ */
+ public function init() {
+
+ if ( $this->is_applicable() ) {
+ \ActionScheduler_AdminView::instance()->process_admin_ui();
+ }
+ }
+
+ /**
+ * Display scheduled actions table.
+ *
+ * @since 2.9.0
+ */
+ public function display() {
+
+ if ( ! $this->is_applicable() ) {
+ return;
+ }
+ ?>
+
+
+
+ Action Scheduler
library, which allows it to queue and process bigger tasks in the background without making your site slower for your visitors. Below you can see the list of all tasks and their status. This table can be very useful when debugging certain issues.', 'wp-mail-smtp' ),
+ [
+ 'a' => [
+ 'href' => [],
+ 'rel' => [],
+ 'target' => [],
+ ],
+ ]
+ ),
+ 'https://actionscheduler.org/'
+ );
+ ?>
+
+
+
+
+ display_debug_events_not_installed();
+ } else {
+ $table = $this->get_table();
+ $table->prepare_items();
+
+ ?>
+
+ check_admin_referer();
+
+ if ( WP::use_global_plugin_settings() && ! current_user_can( 'manage_network_options' ) ) {
+ wp_die( esc_html__( 'You don\'t have the capability to perform this action.', 'wp-mail-smtp' ) );
+ }
+
+ // Unchecked checkboxes doesn't exist in $_POST, so we need to ensure we actually have them in data to save.
+ if ( empty( $data['debug_events']['email_debug'] ) ) {
+ $data['debug_events']['email_debug'] = false;
+ }
+
+ // All the sanitization is done there.
+ $this->options->set( $data, false, false );
+
+ WP::add_admin_notice(
+ esc_html__( 'Settings were successfully saved.', 'wp-mail-smtp' ),
+ WP::ADMIN_NOTICE_SUCCESS
+ );
+ }
+
+ /**
+ * Return an array with information (HTML and id) for each filter for this current view.
+ *
+ * @since 3.0.0
+ *
+ * @return array
+ */
+ private function get_filters_html() {
+
+ $filters = [
+ '.search-box' => $this->get_filter_search_html(),
+ '.wp-mail-smtp-filter-date' => $this->get_filter_date_html(),
+ ];
+
+ return array_filter( $filters );
+ }
+
+ /**
+ * Return HTML with information about the search filter.
+ *
+ * @since 3.0.0
+ *
+ * @return string
+ */
+ private function get_filter_search_html() {
+
+ $table = $this->get_table();
+ $term = $table->get_filtered_search();
+
+ if ( $term === false ) {
+ return '';
+ }
+
+ return sprintf( /* translators: %s The searched term. */
+ __( 'where event contains "%s"', 'wp-mail-smtp' ),
+ '' . esc_html( $term ) . ''
+ );
+ }
+
+ /**
+ * Return HTML with information about the date filter.
+ *
+ * @since 3.0.0
+ *
+ * @return string
+ */
+ private function get_filter_date_html() {
+
+ $table = $this->get_table();
+ $dates = $table->get_filtered_dates();
+
+ if ( $dates === false ) {
+ return '';
+ }
+
+ $dates = array_map(
+ function ( $date ) {
+ return date_i18n( 'M j, Y', strtotime( $date ) );
+ },
+ $dates
+ );
+
+ $html = '';
+
+ switch ( count( $dates ) ) {
+ case 1:
+ $html = sprintf( /* translators: %s - Date. */
+ esc_html__( 'on %s', 'wp-mail-smtp' ),
+ '' . $dates[0] . ''
+ );
+ break;
+ case 2:
+ $html = sprintf( /* translators: %1$s - Date. %2$s - Date. */
+ esc_html__( 'between %1$s and %2$s', 'wp-mail-smtp' ),
+ '' . $dates[0] . '',
+ '' . $dates[1] . ''
+ );
+ break;
+ }
+
+ return $html;
+ }
+
+ /**
+ * Display a message when debug events DB table is missing.
+ *
+ * @since 3.0.0
+ */
+ private function display_debug_events_not_installed() {
+
+ $error_message = get_option( Migration::ERROR_OPTION_NAME );
+
+ $create_missing_tables_url = wp_nonce_url(
+ add_query_arg(
+ [
+ 'create-missing-db-tables' => 1,
+ ],
+ $this->get_link()
+ ),
+ Area::SLUG . '-create-missing-db-tables'
+ );
+
+ $contact_support_url = wp_mail_smtp()->get_utm_url(
+ 'https://wpmailsmtp.com/account/support/',
+ [
+ 'medium' => 'debug-events',
+ 'content' => 'Debug Events not installed correctly',
+ ]
+ );
+ ?>
+
+
+
+
+
+ create the missing DB tables by clicking on this link. If this issue persists, please contact our support and provide the error message below:', 'wp-mail-smtp' ),
+ esc_url( $create_missing_tables_url ),
+ esc_url( $contact_support_url )
+ ),
+ [
+ 'a' => [
+ 'href' => [],
+ 'target' => [],
+ 'rel' => [],
+ ],
+ ]
+ );
+ echo '
';
+ echo '' . esc_html( $error_message ) . '';
+ } else {
+ echo wp_kses(
+ sprintf( /* translators: %1$s - create missing tables link; %2$s - contact support link. */
+ __( 'WP Mail SMTP is using custom database tables for some of its features. In order to work properly, the custom tables should be created, and it seems they are missing. Please try to create the missing DB tables by clicking on this link. If this issue persists, please contact our support.', 'wp-mail-smtp' ),
+ esc_url( $create_missing_tables_url ),
+ esc_url( $contact_support_url )
+ ),
+ [
+ 'a' => [
+ 'href' => [],
+ 'target' => [],
+ 'rel' => [],
+ ],
+ ]
+ );
+ }
+ ?>
+
+
+
+
+ is_pro() ) {
+ // WP Mail SMTP Pro paid installed.
+ $message =
+'Congrats, test email was sent successfully!
+
+Thank you for trying out WP Mail SMTP. We are on a mission to make sure your emails actually get delivered.
+
+- Jared Atchison
+Co-Founder, WP Mail SMTP';
+ } else {
+ // Free WP Mail SMTP is installed.
+ $message =
+'Congrats, test email was sent successfully!
+
+Thank you for trying out WP Mail SMTP. We are on a mission to make sure your emails actually get delivered.
+
+If you find this free plugin useful, please consider giving WP Mail SMTP Pro a try!
+
+https://wpmailsmtp.com/lite-upgrade/
+
+Unlock These Powerful Features with WP Mail SMTP Pro:
+
++ Log all emails and resend failed emails from your email log
++ Track opens and clicks to measure the engagement
++ Get email reports with a weekly summary of your email activity
++ Use a backup mailer if your mail service goes down
++ Get notified of failed emails via email, Slack, or SMS
++ Get help from our world-class support team
+
+- Jared Atchison
+Co-Founder, WP Mail SMTP';
+ }
+ // phpcs:enable
+
+ return $message;
+ }
+
+ /**
+ * Set the HTML content type for a test email.
+ *
+ * @since 1.4.0
+ *
+ * @return string
+ */
+ public static function set_test_html_content_type() {
+
+ return 'text/html';
+ }
+
+ /**
+ * Prepare debug information, that will help users to identify the error.
+ *
+ * @since 1.0.0
+ *
+ * @param MailCatcherInterface $phpmailer The MailCatcher object.
+ * @param string $smtp_debug The SMTP debug message.
+ *
+ * @return string
+ */
+ protected function get_debug_messages( $phpmailer, $smtp_debug ) {
+
+ $connection_options = $this->connection->get_options();
+ $conflicts = new Conflicts();
+
+ $this->debug['mailer'] = $connection_options->get( 'mail', 'mailer' );
+
+ /*
+ * Versions Debug.
+ */
+
+ $versions_text = 'Versions: ';
+
+ $versions_text .= 'WordPress: ' . get_bloginfo( 'version' ) . ' ';
+ $versions_text .= 'WordPress MS: ' . ( is_multisite() ? 'Yes' : 'No' ) . ' ';
+ $versions_text .= 'PHP: ' . PHP_VERSION . ' ';
+ $versions_text .= 'WP Mail SMTP: ' . WPMS_PLUGIN_VER . ' ';
+
+ /*
+ * Mailer Debug.
+ */
+
+ $mailer_text = 'Params: ';
+
+ $mailer_text .= 'Mailer: ' . $this->debug['mailer'] . ' ';
+ $mailer_text .= 'Constants: ' . ( $connection_options->is_const_enabled() ? 'Yes' : 'No' ) . ' ';
+
+ if ( $conflicts->is_detected() ) {
+ $conflict_plugin_names = implode( ', ', $conflicts->get_all_conflict_names() );
+
+ $mailer_text .= 'Conflicts: ' . esc_html( $conflict_plugin_names ) . ' ';
+ }
+
+ // Display different debug info based on the mailer.
+ $mailer = wp_mail_smtp()->get_providers()->get_mailer( $this->debug['mailer'], $phpmailer, $this->connection );
+
+ if ( $mailer ) {
+ $mailer_text .= $mailer->get_debug_info();
+ }
+
+ $phpmailer_error = $phpmailer->ErrorInfo; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
+
+ // Append any PHPMailer errors to the mailer debug (except SMTP mailer, which has the full error output below).
+ if (
+ ! empty( $phpmailer_error ) &&
+ ! $connection_options->is_mailer_smtp()
+ ) {
+ $mailer_text .= '
';
+ }
+
+ /**
+ * Returns debug information for detection, processing, and display.
+ *
+ * @since 1.3.0
+ *
+ * @return array
+ */
+ protected function get_debug_details() {
+
+ $connection_options = $this->connection->get_options();
+ $smtp_host = $connection_options->get( 'smtp', 'host' );
+ $smtp_port = $connection_options->get( 'smtp', 'port' );
+ $smtp_encryption = $connection_options->get( 'smtp', 'encryption' );
+
+ $details = [
+ // [any] - cURL error 60/77.
+ [
+ 'mailer' => 'any',
+ 'errors' => [
+ [ 'cURL error 60' ],
+ [ 'cURL error 77' ],
+ ],
+ 'title' => esc_html__( 'SSL certificate issue.', 'wp-mail-smtp' ),
+ 'description' => [
+ esc_html__( 'This means your web server cannot reliably make secure connections (make requests to HTTPS sites).', 'wp-mail-smtp' ),
+ esc_html__( 'Typically this error is returned when web server is not configured properly.', 'wp-mail-smtp' ),
+ ],
+ 'steps' => [
+ esc_html__( 'Contact your web hosting provider and inform them your site has an issue with SSL certificates.', 'wp-mail-smtp' ),
+ esc_html__( 'The exact error you can provide them is in the Error log, available at the bottom of this page.', 'wp-mail-smtp' ),
+ esc_html__( 'Ask them to resolve the issue then try again.', 'wp-mail-smtp' ),
+ ],
+ ],
+ // [any] - cURL error 6/7.
+ [
+ 'mailer' => 'any',
+ 'errors' => [
+ [ 'cURL error 6' ],
+ [ 'cURL error 7' ],
+ ],
+ 'title' => esc_html__( 'Could not connect to host.', 'wp-mail-smtp' ),
+ 'description' => [
+ ! empty( $smtp_host )
+ ? sprintf( /* translators: %s - SMTP host address. */
+ esc_html__( 'This means your web server was unable to connect to %s.', 'wp-mail-smtp' ),
+ $smtp_host
+ )
+ : esc_html__( 'This means your web server was unable to connect to the host server.', 'wp-mail-smtp' ),
+ esc_html__( 'Typically this error is returned your web server is blocking the connections or the SMTP host denying the request.', 'wp-mail-smtp' ),
+ ],
+ 'steps' => [
+ sprintf( /* translators: %s - SMTP host address. */
+ esc_html__( 'Contact your web hosting provider and ask them to verify your server can connect to %s. Additionally, ask them if a firewall or security policy may be preventing the connection.', 'wp-mail-smtp' ),
+ $smtp_host
+ ),
+ esc_html__( 'If using "Other SMTP" Mailer, triple check your SMTP settings including host address, email, and password.', 'wp-mail-smtp' ),
+ esc_html__( 'If using "Other SMTP" Mailer, contact your SMTP host to confirm they are accepting outside connections with the settings you have configured (address, username, port, security, etc).', 'wp-mail-smtp' ),
+ ],
+ ],
+ // [sendgrid] - cURL error 18 - potential incorrect API key.
+ [
+ 'mailer' => 'sendgrid',
+ 'errors' => [
+ [ 'cURL error 18' ],
+ ],
+ 'title' => esc_html__( 'Invalid SendGrid API key', 'wp-mail-smtp' ),
+ 'description' => [
+ esc_html__( 'It looks like your SendGrid API Key is invalid.', 'wp-mail-smtp' ),
+ ],
+ 'steps' => [
+ esc_html__( 'Go to WP Mail SMTP plugin Settings page.', 'wp-mail-smtp' ),
+ esc_html__( 'Make sure your API Key in the SendGrid mailer settings is correct and valid.', 'wp-mail-smtp' ),
+ esc_html__( 'Save the plugin settings.', 'wp-mail-smtp' ),
+ esc_html__( 'If updating the API Key doesn\'t resolve this issue, please contact our support.', 'wp-mail-smtp' ),
+ ],
+ ],
+ // [any] - cURL error XX (other).
+ [
+ 'mailer' => 'any',
+ 'errors' => [
+ [ 'cURL error' ],
+ ],
+ 'title' => esc_html__( 'Could not connect to your host.', 'wp-mail-smtp' ),
+ 'description' => [
+ ! empty( $smtp_host )
+ ? sprintf( /* translators: %s - SMTP host address. */
+ esc_html__( 'This means your web server was unable to connect to %s.', 'wp-mail-smtp' ),
+ $smtp_host
+ )
+ : esc_html__( 'This means your web server was unable to connect to the host server.', 'wp-mail-smtp' ),
+ esc_html__( 'Typically this error is returned when web server is not configured properly.', 'wp-mail-smtp' ),
+ ],
+ 'steps' => [
+ esc_html__( 'Contact your web hosting provider and inform them you are having issues making outbound connections.', 'wp-mail-smtp' ),
+ esc_html__( 'The exact error you can provide them is in the Error log, available at the bottom of this page.', 'wp-mail-smtp' ),
+ esc_html__( 'Ask them to resolve the issue then try again.', 'wp-mail-smtp' ),
+ ],
+ ],
+ // [smtp] - SMTP Error: Count not authenticate.
+ [
+ 'mailer' => 'smtp',
+ 'errors' => [
+ [ 'SMTP Error: Could not authenticate.' ],
+ ],
+ 'title' => esc_html__( 'Could not authenticate your SMTP account.', 'wp-mail-smtp' ),
+ 'description' => [
+ esc_html__( 'This means we were able to connect to your SMTP host, but were not able to proceed using the email/password in the settings.', 'wp-mail-smtp' ),
+ esc_html__( 'Typically this error is returned when the email or password is not correct or is not what the SMTP host is expecting.', 'wp-mail-smtp' ),
+ ],
+ 'steps' => [
+ esc_html__( 'Triple check your SMTP settings including host address, email, and password. If you have recently reset your password you will need to update the settings.', 'wp-mail-smtp' ),
+ esc_html__( 'Contact your SMTP host to confirm you are using the correct username and password.', 'wp-mail-smtp' ),
+ esc_html__( 'Verify with your SMTP host that your account has permissions to send emails using outside connections.', 'wp-mail-smtp' ),
+ sprintf(
+ wp_kses( /* translators: %s - URL to the wpmailsmtp.com doc page. */
+ __( 'Visit our documentation for additional tips on how to resolve this error.', 'wp-mail-smtp' ),
+ [
+ 'a' => [
+ 'href' => [],
+ 'target' => [],
+ 'rel' => [],
+ ],
+ ]
+ ),
+ // phpcs:ignore WordPress.Arrays.ArrayDeclarationSpacing.AssociativeArrayFound
+ esc_url( wp_mail_smtp()->get_utm_url( 'https://wpmailsmtp.com/docs/how-to-set-up-the-other-smtp-mailer-in-wp-mail-smtp/#auth-type', [ 'medium' => 'email-test', 'content' => 'Other SMTP auth debug - our documentation' ] ) )
+ ),
+ ],
+ ],
+ // [smtp] - Sending bulk email, hitting rate limit.
+ [
+ 'mailer' => 'smtp',
+ 'errors' => [
+ [ 'We do not authorize the use of this system to transport unsolicited' ],
+ ],
+ 'title' => esc_html__( 'Error due to unsolicited and/or bulk e-mail.', 'wp-mail-smtp' ),
+ 'description' => [
+ esc_html__( 'This means the connection to your SMTP host was made successfully, but the host rejected the email.', 'wp-mail-smtp' ),
+ esc_html__( 'Typically this error is returned when you are sending too many e-mails or e-mails that have been identified as spam.', 'wp-mail-smtp' ),
+ ],
+ 'steps' => [
+ esc_html__( 'Make sure you are not sending emails with too many recipients. Example: single email should not have 10+ recipients. You can install any WordPress e-mail logging plugin to check your recipients (TO, CC and BCC).', 'wp-mail-smtp' ),
+ esc_html__( 'Contact your SMTP host to ask about sending/rate limits.', 'wp-mail-smtp' ),
+ esc_html__( 'Verify with them your SMTP account is in good standing and your account has not been flagged.', 'wp-mail-smtp' ),
+ ],
+ ],
+ // [smtp] - Unauthenticated senders not allowed.
+ [
+ 'mailer' => 'smtp',
+ 'errors' => [
+ [ 'Unauthenticated senders not allowed' ],
+ ],
+ 'title' => esc_html__( 'Unauthenticated senders are not allowed.', 'wp-mail-smtp' ),
+ 'description' => [
+ esc_html__( 'This means the connection to your SMTP host was made successfully, but you should enable Authentication and provide correct Username and Password.', 'wp-mail-smtp' ),
+ ],
+ 'steps' => [
+ esc_html__( 'Go to WP Mail SMTP plugin Settings page.', 'wp-mail-smtp' ),
+ esc_html__( 'Enable Authentication', 'wp-mail-smtp' ),
+ esc_html__( 'Enter correct SMTP Username (usually this is an email address) and Password in the appropriate fields.', 'wp-mail-smtp' ),
+ ],
+ ],
+ // [smtp] - certificate verify failed.
+ // Has to be defined before "SMTP connect() failed" error, since this is a more specific error,
+ // which contains the "SMTP connect() failed" error message as well.
+ [
+ 'mailer' => 'smtp',
+ 'errors' => [
+ [ 'certificate verify failed' ],
+ ],
+ 'title' => esc_html__( 'Misconfigured server certificate.', 'wp-mail-smtp' ),
+ 'description' => [
+ esc_html__( 'This means OpenSSL on your server isn\'t able to verify the host certificate.', 'wp-mail-smtp' ),
+ esc_html__( 'There are a few reasons why this is happening. It could be that the host certificate is misconfigured, or this server\'s OpenSSL is using an outdated CA bundle.', 'wp-mail-smtp' ),
+ ],
+ 'steps' => [
+ esc_html__( 'Verify that the host\'s SSL certificate is valid.', 'wp-mail-smtp' ),
+ sprintf(
+ wp_kses( /* translators: %s - URL to the PHP openssl manual */
+ __( 'Contact your hosting support, show them the "full Error Log for debugging" below and share this link with them.', 'wp-mail-smtp' ),
+ [
+ 'a' => [
+ 'href' => [],
+ 'target' => [],
+ 'rel' => [],
+ ],
+ ]
+ ),
+ 'https://www.php.net/manual/en/migration56.openssl.php'
+ ),
+ ],
+ ],
+ // [smtp] - SMTP connect() failed.
+ [
+ 'mailer' => 'smtp',
+ 'errors' => [
+ [ 'SMTP connect() failed' ],
+ ],
+ 'title' => esc_html__( 'Could not connect to the SMTP host.', 'wp-mail-smtp' ),
+ 'description' => [
+ ! empty( $smtp_host )
+ ? sprintf( /* translators: %s - SMTP host address. */
+ esc_html__( 'This means your web server was unable to connect to %s.', 'wp-mail-smtp' ),
+ $smtp_host
+ )
+ : esc_html__( 'This means your web server was unable to connect to the host server.', 'wp-mail-smtp' ),
+ esc_html__( 'Typically this error is returned for one of the following reasons:', 'wp-mail-smtp' ),
+ '
' .
+ esc_html__( 'Your web server is blocking the connection.', 'wp-mail-smtp' )
+ . '
'
+ . '
' .
+ esc_html__( 'Your SMTP host is rejecting the connection.', 'wp-mail-smtp' )
+ . '
'
+ . '
',
+ ],
+ 'steps' => [
+ esc_html__( 'Triple check your SMTP settings including host address, email, and password, port, and security.', 'wp-mail-smtp' ),
+ sprintf(
+ wp_kses( /* translators: %1$s - SMTP host address, %2$s - SMTP port, %3$s - SMTP encryption. */
+ __( 'Contact your web hosting provider and ask them to verify your server can connect to %1$s on port %2$s using %3$s encryption. Additionally, ask them if a firewall or security policy may be preventing the connection - many shared hosts block certain ports. Note: this is the most common cause of this issue.', 'wp-mail-smtp' ),
+ [
+ 'a' => [
+ 'href' => [],
+ 'rel' => [],
+ 'target' => [],
+ ],
+ 'strong' => [],
+ 'br' => [],
+ ]
+ ),
+ $smtp_host,
+ $smtp_port,
+ 'none' === $smtp_encryption ? esc_html__( 'no', 'wp-mail-smtp' ) : $smtp_encryption
+ ),
+ esc_html__( 'Contact your SMTP host to confirm you are using the correct username and password.', 'wp-mail-smtp' ),
+ esc_html__( 'Verify with your SMTP host that your account has permissions to send emails using outside connections.', 'wp-mail-smtp' ),
+ ],
+ ],
+ // [mailgun] - Please activate your Mailgun account.
+ [
+ 'mailer' => 'mailgun',
+ 'errors' => [
+ [ 'Please activate your Mailgun account' ],
+ ],
+ 'title' => esc_html__( 'Mailgun failed.', 'wp-mail-smtp' ),
+ 'description' => [
+ esc_html__( 'It seems that you forgot to activate your Mailgun account.', 'wp-mail-smtp' ),
+ ],
+ 'steps' => [
+ esc_html__( 'Check your inbox you used to create a Mailgun account. Click the activation link in an email from Mailgun.', 'wp-mail-smtp' ),
+ esc_html__( 'If you do not see activation email, go to your Mailgun control panel and resend the activation email.', 'wp-mail-smtp' ),
+ ],
+ ],
+ // [mailgun] - Forbidden.
+ [
+ 'mailer' => 'mailgun',
+ 'errors' => [
+ [ 'Forbidden' ],
+ ],
+ 'title' => esc_html__( 'Mailgun failed.', 'wp-mail-smtp' ),
+ 'description' => [
+ esc_html__( 'Typically this error occurs because there is an issue with your Mailgun settings, in many cases Mailgun API Key, Domain Name, or Region is incorrect.', 'wp-mail-smtp' ),
+ ],
+ 'steps' => [
+ sprintf(
+ wp_kses( /* translators: %1$s - Mailgun API Key area URL. */
+ __( 'Go to your Mailgun account and verify that your Mailgun API Key is correct.', 'wp-mail-smtp' ),
+ [
+ 'a' => [
+ 'href' => [],
+ 'rel' => [],
+ 'target' => [],
+ ],
+ ]
+ ),
+ 'https://app.mailgun.com/settings/api_security'
+ ),
+ sprintf(
+ wp_kses( /* translators: %1$s - Mailgun domains area URL. */
+ __( 'Verify your Domain Name is correct.', 'wp-mail-smtp' ),
+ [
+ 'a' => [
+ 'href' => [],
+ 'rel' => [],
+ 'target' => [],
+ ],
+ ]
+ ),
+ 'https://app.mailgun.com/mg/sending/domains'
+ ),
+ esc_html__( 'Verify your domain Region is correct.', 'wp-mail-smtp' ),
+ ],
+ ],
+ // [mailgun] - Free accounts are for test purposes only.
+ [
+ 'mailer' => 'mailgun',
+ 'errors' => [
+ [ 'Free accounts are for test purposes only' ],
+ ],
+ 'title' => esc_html__( 'Mailgun failed.', 'wp-mail-smtp' ),
+ 'description' => [
+ esc_html__( 'Your Mailgun account does not have access to send emails.', 'wp-mail-smtp' ),
+ esc_html__( 'Typically this error occurs because you have not set up and/or complete domain name verification for your Mailgun account.', 'wp-mail-smtp' ),
+ ],
+ 'steps' => [
+ sprintf(
+ wp_kses( /* translators: %s - Mailgun documentation URL. */
+ __( 'Go to our how-to guide for setting up Mailgun with WP Mail SMTP.', 'wp-mail-smtp' ),
+ [
+ 'a' => [
+ 'href' => [],
+ 'rel' => [],
+ 'target' => [],
+ ],
+ ]
+ ),
+ // phpcs:ignore WordPress.Arrays.ArrayDeclarationSpacing.AssociativeArrayFound
+ esc_url( wp_mail_smtp()->get_utm_url( 'https://wpmailsmtp.com/docs/how-to-set-up-the-mailgun-mailer-in-wp-mail-smtp/', [ 'medium' => 'email-test', 'content' => 'Mailgun with WP Mail SMTP' ] ) )
+ ),
+ esc_html__( 'Complete the steps in section "2. Verify Your Domain".', 'wp-mail-smtp' ),
+ ],
+ ],
+ // [gmail] - 401: Login Required.
+ [
+ 'mailer' => 'gmail',
+ 'errors' => [
+ [ '401', 'Login Required' ],
+ ],
+ 'title' => esc_html__( 'Google API Error.', 'wp-mail-smtp' ),
+ 'description' => [
+ esc_html__( 'You have not properly configured Gmail mailer.', 'wp-mail-smtp' ),
+ esc_html__( 'Make sure that you have clicked the "Allow plugin to send emails using your Google account" button under Gmail settings.', 'wp-mail-smtp' ),
+ ],
+ 'steps' => [
+ esc_html__( 'Go to plugin Settings page and click the "Allow plugin to send emails using your Google account" button.', 'wp-mail-smtp' ),
+ esc_html__( 'After the click you should be redirected to a Gmail authorization screen, where you will be asked a permission to send emails on your behalf.', 'wp-mail-smtp' ),
+ esc_html__( 'Please click "Agree", if you see that button. If not - you will need to enable less secure apps first:', 'wp-mail-smtp' )
+ . '
'
+ . '
' .
+ sprintf(
+ wp_kses( /* translators: %s - Google support article URL. */
+ __( 'if you are using regular Gmail account, please read this article to proceed.', 'wp-mail-smtp' ),
+ [
+ 'a' => [
+ 'href' => [],
+ 'target' => [],
+ 'rel' => [],
+ ],
+ ]
+ ),
+ 'https://support.google.com/accounts/answer/6010255?hl=en'
+ )
+ . '
'
+ . '
' .
+ sprintf(
+ wp_kses( /* translators: %s - Google support article URL. */
+ __( 'if you are using Google Workspace, please read this article to proceed.', 'wp-mail-smtp' ),
+ [
+ 'a' => [
+ 'href' => [],
+ 'target' => [],
+ 'rel' => [],
+ ],
+ ]
+ ),
+ 'https://support.google.com/cloudidentity/answer/6260879?hl=en'
+ )
+ . '
'
+ . '
',
+ ],
+ ],
+ // [gmail] - 400: Recipient address required.
+ [
+ 'mailer' => 'gmail',
+ 'errors' => [
+ [ '400', 'Recipient address required' ],
+ ],
+ 'title' => esc_html__( 'Google API Error.', 'wp-mail-smtp' ),
+ 'description' => [
+ esc_html__( 'Typically this error occurs because the address to which the email was sent to is invalid or was empty.', 'wp-mail-smtp' ),
+ ],
+ 'steps' => [
+ esc_html__( 'Check the "Send To" email address used and confirm it is a valid email and was not empty.', 'wp-mail-smtp' ),
+ sprintf( /* translators: 1 - correct email address example. 2 - incorrect email address example. */
+ esc_html__( 'It should be something like this: %1$s. These are incorrect values: %2$s.', 'wp-mail-smtp' ),
+ 'info@example.com',
+ 'info@localhost, info@192.168.1.1'
+ ),
+ esc_html__( 'Make sure that the generated email has a TO header, useful when you are responsible for email creation.', 'wp-mail-smtp' ),
+ ],
+ ],
+ // [gmail] - Token has been expired or revoked.
+ [
+ 'mailer' => 'gmail',
+ 'errors' => [
+ [ 'invalid_grant', 'Token has been expired or revoked' ],
+ ],
+ 'title' => esc_html__( 'Google API Error.', 'wp-mail-smtp' ),
+ 'description' => [
+ esc_html__( 'Unfortunately, this error can be due to many different reasons.', 'wp-mail-smtp' ),
+ sprintf(
+ wp_kses( /* translators: %s - Blog article URL. */
+ __( 'Please read this article to learn more about what can cause this error and follow the steps below.', 'wp-mail-smtp' ),
+ [
+ 'a' => [
+ 'href' => [],
+ 'target' => [],
+ 'rel' => [],
+ ],
+ ]
+ ),
+ 'https://blog.timekit.io/google-oauth-invalid-grant-nightmare-and-how-to-fix-it-9f4efaf1da35'
+ ),
+ ],
+ 'steps' => [
+ esc_html__( 'Go to WP Mail SMTP plugin settings page. Click the āRemove OAuth Connectionā button.', 'wp-mail-smtp' ),
+ esc_html__( 'Then click the āAllow plugin to send emails using your Google accountā button and re-enable access.', 'wp-mail-smtp' ),
+ ],
+ ],
+ // [gmail] - Code was already redeemed.
+ [
+ 'mailer' => 'gmail',
+ 'errors' => [
+ [ 'invalid_grant', 'Code was already redeemed' ],
+ ],
+ 'title' => esc_html__( 'Google API Error.', 'wp-mail-smtp' ),
+ 'description' => [
+ esc_html__( 'Authentication code that Google returned to you has already been used on your previous auth attempt.', 'wp-mail-smtp' ),
+ ],
+ 'steps' => [
+ esc_html__( 'Make sure that you are not trying to manually clean up the plugin options to retry the "Allow..." step.', 'wp-mail-smtp' ),
+ esc_html__( 'Reinstall the plugin with clean plugin data turned on on Misc page. This will remove all the plugin options and you will be safe to retry.', 'wp-mail-smtp' ),
+ esc_html__( 'Make sure there is no aggressive caching on site admin area pages or try to clean cache between attempts.', 'wp-mail-smtp' ),
+ ],
+ ],
+ // [gmail] - 400: Mail service not enabled.
+ [
+ 'mailer' => 'gmail',
+ 'errors' => [
+ [ '400', 'Mail service not enabled' ],
+ ],
+ 'title' => esc_html__( 'Google API Error.', 'wp-mail-smtp' ),
+ 'description' => [
+ esc_html__( 'There are various reasons for that, please review the steps below.', 'wp-mail-smtp' ),
+ ],
+ 'steps' => [
+ sprintf(
+ wp_kses( /* translators: %s - Google Workspace Admin area URL. */
+ __( 'Make sure that your Google Workspace trial period has not expired. You can check the status here.', 'wp-mail-smtp' ),
+ [
+ 'a' => [
+ 'href' => [],
+ 'rel' => [],
+ 'target' => [],
+ ],
+ ]
+ ),
+ 'https://admin.google.com'
+ ),
+ sprintf(
+ wp_kses( /* translators: %s - Google Workspace Admin area URL. */
+ __( 'Make sure that Gmail app in your Google Workspace is actually enabled. You can check that in Apps list in Google Workspace Admin area.', 'wp-mail-smtp' ),
+ [
+ 'a' => [
+ 'href' => [],
+ 'rel' => [],
+ 'target' => [],
+ ],
+ ]
+ ),
+ 'https://admin.google.com'
+ ),
+ sprintf(
+ wp_kses( /* translators: %s - Google Developers Console URL. */
+ __( 'Make sure that you have Gmail API enabled, and you can do that here.', 'wp-mail-smtp' ),
+ [
+ 'a' => [
+ 'href' => [],
+ 'rel' => [],
+ 'target' => [],
+ ],
+ ]
+ ),
+ 'https://console.developers.google.com/'
+ ),
+ ],
+ ],
+ // [gmail] - 403: Project X is not found and cannot be used for API calls.
+ [
+ 'mailer' => 'gmail',
+ 'errors' => [
+ [ '403', 'is not found and cannot be used for API calls' ],
+ ],
+ 'title' => esc_html__( 'Google API Error.', 'wp-mail-smtp' ),
+ 'description' => [],
+ 'steps' => [
+ esc_html__( 'Make sure that the used Client ID/Secret correspond to a proper project that has Gmail API enabled.', 'wp-mail-smtp' ),
+ sprintf(
+ wp_kses( /* translators: %s - Gmail documentation URL. */
+ esc_html__( 'Please follow our Gmail tutorial to be sure that all the correct project and data is applied.', 'wp-mail-smtp' ),
+ [
+ 'a' => [
+ 'href' => [],
+ 'rel' => [],
+ 'target' => [],
+ ],
+ ]
+ ),
+ // phpcs:ignore WordPress.Arrays.ArrayDeclarationSpacing.AssociativeArrayFound
+ esc_url( wp_mail_smtp()->get_utm_url( 'https://wpmailsmtp.com/docs/how-to-set-up-the-gmail-mailer-in-wp-mail-smtp/', [ 'medium' => 'email-test', 'content' => 'Gmail tutorial' ] ) )
+ ),
+ ],
+ ],
+ // [gmail] - The OAuth client was disabled.
+ [
+ 'mailer' => 'gmail',
+ 'errors' => [
+ [ 'disabled_client', 'The OAuth client was disabled' ],
+ ],
+ 'title' => esc_html__( 'Google API Error.', 'wp-mail-smtp' ),
+ 'description' => [
+ esc_html__( 'You may have added a new API to a project', 'wp-mail-smtp' ),
+ ],
+ 'steps' => [
+ esc_html__( 'Make sure that the used Client ID/Secret correspond to a proper project that has Gmail API enabled.', 'wp-mail-smtp' ),
+ esc_html__( 'Try to use a separate project for your emails, so the project has only 1 Gmail API in it enabled. You will need to remove the old project and create a new one from scratch.', 'wp-mail-smtp' ),
+ ],
+ ],
+ // [SMTP.com] - The "channel - not found" issue.
+ [
+ 'mailer' => 'smtpcom',
+ 'errors' => [
+ [ 'channel - not found' ],
+ ],
+ 'title' => esc_html__( 'SMTP.com API Error.', 'wp-mail-smtp' ),
+ 'description' => [
+ esc_html__( 'Your Sender Name option is incorrect.', 'wp-mail-smtp' ),
+ ],
+ 'steps' => [
+ esc_html__( 'Please make sure you entered an accurate Sender Name in WP Mail SMTP plugin settings.', 'wp-mail-smtp' ),
+ ],
+ ],
+ // [gmail] - GuzzleHttp requires cURL, the allow_url_fopen ini setting, or a custom HTTP handler.
+ [
+ 'mailer' => 'gmail',
+ 'errors' => [
+ [ 'GuzzleHttp requires cURL, the allow_url_fopen ini setting, or a custom HTTP handler' ],
+ ],
+ 'title' => esc_html__( 'GuzzleHttp requirements.', 'wp-mail-smtp' ),
+ 'description' => [
+ esc_html__( 'GuzzleHttp requires cURL, the allow_url_fopen ini setting, or a custom HTTP handler.', 'wp-mail-smtp' ),
+ ],
+ 'steps' => [
+ esc_html__( 'Edit your php.ini file on your hosting server.', 'wp-mail-smtp' ),
+ esc_html__( '(Recommended) Enable PHP extension: cURL, by adding "extension=curl" to the php.ini file (without the quotation marks) OR', 'wp-mail-smtp' ),
+ esc_html__( '(If cURL can\'t be enabled on your hosting server) Enable PHP setting: allow_url_fopen, by adding "allow_url_fopen = On" to the php.ini file (without the quotation marks)', 'wp-mail-smtp' ),
+ esc_html__( 'If you don\'t know how to do the above we strongly suggest contacting your hosting support and provide them the "full Error Log for debugging" below and these steps. They should be able to fix this issue for you.', 'wp-mail-smtp' ),
+ ],
+ ],
+ // [sparkpost] - Forbidden.
+ [
+ 'mailer' => 'sparkpost',
+ 'errors' => [
+ [ 'Forbidden' ],
+ ],
+ 'title' => esc_html__( 'SparkPost API failed.', 'wp-mail-smtp' ),
+ 'description' => [
+ esc_html__( 'Typically this error occurs because there is an issue with your SparkPost settings, in many cases an incorrect API key.', 'wp-mail-smtp' ),
+ ],
+ 'steps' => [
+ sprintf(
+ wp_kses( /* translators: %1$s - SparkPost API Keys area URL, %1$s - SparkPost EU API Keys area URL. */
+ __( 'Go to your SparkPost account or SparkPost EU account and verify that your API key is correct.', 'wp-mail-smtp' ),
+ [
+ 'a' => [
+ 'href' => [],
+ 'rel' => [],
+ 'target' => [],
+ ],
+ 'b' => [],
+ ]
+ ),
+ 'https://app.sparkpost.com/account/api-keys',
+ 'https://app.eu.sparkpost.com/account/api-keys'
+ ),
+ esc_html__( 'Verify that your API key has "Transmissions: Read/Write" permission.', 'wp-mail-smtp' ),
+ ],
+ ],
+ // [sparkpost] - Unauthorized.
+ [
+ 'mailer' => 'sparkpost',
+ 'errors' => [
+ [ 'Unauthorized' ],
+ ],
+ 'title' => esc_html__( 'SparkPost API failed.', 'wp-mail-smtp' ),
+ 'description' => [
+ esc_html__( 'Typically this error occurs because there is an issue with your SparkPost settings, in many cases an incorrect region.', 'wp-mail-smtp' ),
+ ],
+ 'steps' => [
+ esc_html__( 'Verify that your SparkPost account region is selected in WP Mail SMTP settings.', 'wp-mail-smtp' ),
+ ],
+ ],
+ ];
+
+ /**
+ * [any] - PHP 7.4.x and PCRE library issues.
+ *
+ * @see https://wordpress.org/support/topic/cant-send-emails-using-php-7-4/
+ */
+ if (
+ version_compare( phpversion(), '7.4', '>=' ) &&
+ defined( 'PCRE_VERSION' ) &&
+ version_compare( PCRE_VERSION, '10.0', '>' ) &&
+ version_compare( PCRE_VERSION, '10.32', '<=' )
+ ) {
+ $details[] = [
+ 'mailer' => 'any',
+ 'errors' => [
+ [ 'Invalid address: (setFrom)' ],
+ ],
+ 'title' => esc_html__( 'PCRE library issue', 'wp-mail-smtp' ),
+ 'description' => [
+ esc_html__( 'It looks like your server is running PHP version 7.4.x with an outdated PCRE library (libpcre2) that has a known issue with email address validation.', 'wp-mail-smtp' ),
+ esc_html__( 'There is a known issue with PHP version 7.4.x, when using libpcre2 library version lower than 10.33.', 'wp-mail-smtp' ),
+ ],
+ 'steps' => [
+ esc_html__( 'Contact your web hosting provider and inform them you are having issues with libpcre2 library on PHP 7.4.', 'wp-mail-smtp' ),
+ esc_html__( 'They should be able to resolve this issue for you.', 'wp-mail-smtp' ),
+ esc_html__( 'For a quick fix, until your web hosting resolves this, you can downgrade to PHP version 7.3 on your server.', 'wp-mail-smtp' ),
+ ],
+ ];
+ }
+
+ // Error detection logic.
+ foreach ( $details as $data ) {
+
+ // Check for appropriate mailer.
+ if ( 'any' !== $data['mailer'] && $this->debug['mailer'] !== $data['mailer'] ) {
+ continue;
+ }
+
+ $match = false;
+
+ // Attempt to detect errors.
+ foreach ( $data['errors'] as $error_group ) {
+ foreach ( $error_group as $error_message ) {
+ $match = false !== strpos( $this->debug['error_log'], $error_message );
+ if ( ! $match ) {
+ break;
+ }
+ }
+ if ( $match ) {
+ break;
+ }
+ }
+
+ if ( $match ) {
+ return $data;
+ }
+ }
+
+ // Return defaults.
+ return [
+ 'title' => esc_html__( 'An issue was detected.', 'wp-mail-smtp' ),
+ 'description' => [
+ esc_html__( 'This means your test email was unable to be sent.', 'wp-mail-smtp' ),
+ esc_html__( 'Typically this error is returned for one of the following reasons:', 'wp-mail-smtp' ),
+ '
+ limited support on the WordPress.org support forums. You can create a support thread there, but please understand that free support is not guaranteed and is limited to simple issues. If you have an urgent or complex issue, then please consider upgrading to WP Mail SMTP Pro to access our priority support ticket system.', 'wp-mail-smtp' ),
+ array(
+ 'a' => array(
+ 'href' => array(),
+ 'rel' => array(),
+ 'target' => array(),
+ ),
+ )
+ ),
+ 'https://wordpress.org/support/topic/wp-mail-smtp-support-policy/',
+ 'https://wordpress.org/support/plugin/wp-mail-smtp/',
+ esc_url( wp_mail_smtp()->get_upgrade_link( 'email-test-fail' ) )
+ );
+ ?>
+
+
+ get_capability_manage_options() ) ) {
+ return;
+ }
+
+ $conflicts = new Conflicts();
+
+ if ( $conflicts->is_detected() ) {
+ $conflicts->notify();
+ }
+ }
+
+ /**
+ * Init the \PHPMailer replacement.
+ *
+ * @since 1.0.0
+ *
+ * @return MailCatcherInterface
+ */
+ public function replace_phpmailer() {
+
+ global $phpmailer;
+
+ return $this->replace_w_fake_phpmailer( $phpmailer );
+ }
+
+ /**
+ * Overwrite default PhpMailer with our MailCatcher.
+ *
+ * @since 1.0.0
+ * @since 1.5.0 Throw external PhpMailer exceptions, inherits default WP behavior.
+ *
+ * @param null $obj PhpMailer object to override with own implementation.
+ *
+ * @return MailCatcherInterface
+ */
+ protected function replace_w_fake_phpmailer( &$obj = null ) {
+
+ $obj = $this->generate_mail_catcher( true );
+
+ return $obj;
+ }
+
+ /**
+ * What to do on plugin activation.
+ *
+ * @since 1.0.0
+ * @since 2.0.0 Changed from general `plugin_activate` hook to this plugin specific activation hook.
+ */
+ public function activate() {
+
+ // Store the plugin version when initial install occurred.
+ add_option( 'wp_mail_smtp_initial_version', WPMS_PLUGIN_VER, '', false );
+
+ // Store the plugin version activated to reference with upgrades.
+ update_option( 'wp_mail_smtp_version', WPMS_PLUGIN_VER, false );
+
+ // Save default options, only once.
+ Options::init()->set( Options::get_defaults(), true );
+
+ /**
+ * Store the timestamp of first plugin activation.
+ *
+ * @since 2.1.0
+ */
+ add_option( 'wp_mail_smtp_activated_time', time(), '', false );
+
+ /**
+ * Store the timestamp of the first plugin activation by license type.
+ *
+ * @since 2.3.0
+ */
+ $license_type = is_readable( $this->plugin_path . '/src/Pro/Pro.php' ) ? 'pro' : 'lite';
+ $activated = get_option( 'wp_mail_smtp_activated', [] );
+
+ if ( empty( $activated[ $license_type ] ) ) {
+ $activated[ $license_type ] = time();
+ update_option( 'wp_mail_smtp_activated', $activated );
+ }
+
+ set_transient( 'wp_mail_smtp_just_activated', true, 60 );
+
+ // Add transient to trigger redirect to the Setup Wizard.
+ set_transient( 'wp_mail_smtp_activation_redirect', true, 30 );
+ }
+
+ /**
+ * Whether this is a Pro version of a plugin.
+ *
+ * @since 1.5.0
+ *
+ * @return bool
+ */
+ public function is_pro() {
+
+ return apply_filters( 'wp_mail_smtp_core_is_pro', ! empty( $this->pro ) );
+ }
+
+ /**
+ * Get the current license type.
+ *
+ * @since 1.5.0
+ *
+ * @return string Default value: lite.
+ */
+ public function get_license_type() {
+
+ $type = Options::init()->get( 'license', 'type' );
+
+ if ( empty( $type ) ) {
+ $type = 'lite';
+ }
+
+ return strtolower( $type );
+ }
+
+ /**
+ * Get the current license key.
+ *
+ * @since 1.5.0
+ *
+ * @return string
+ */
+ public function get_license_key() {
+
+ $key = Options::init()->get( 'license', 'key' );
+
+ if ( empty( $key ) ) {
+ $key = '';
+ }
+
+ return $key;
+ }
+
+ /**
+ * Upgrade link used within the various admin pages.
+ *
+ * @since 1.5.0
+ * @since 1.5.1 Support all UTM params.
+ *
+ * @param array|string $utm Array of UTM params, or if string provided - utm_content URL parameter.
+ *
+ * @return string
+ */
+ public function get_upgrade_link( $utm ) {
+
+ $url = $this->get_utm_url( 'https://wpmailsmtp.com/lite-upgrade/', $utm );
+
+ /**
+ * Filters upgrade link.
+ *
+ * @since 1.5.0
+ *
+ * @param string $url Upgrade link.
+ */
+ return apply_filters( 'wp_mail_smtp_core_get_upgrade_link', $url );
+ }
+
+ /**
+ * Get UTM URL.
+ *
+ * @since 3.4.0
+ *
+ * @param string $url Base url.
+ * @param array|string $utm Array of UTM params, or if string provided - utm_content URL parameter.
+ *
+ * @return string
+ */
+ public function get_utm_url( $url, $utm ) { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh
+
+ // Defaults.
+ $source = 'WordPress';
+ $medium = 'plugin-settings';
+ $campaign = $this->is_pro() ? 'plugin' : 'liteplugin';
+ $content = 'general';
+ $locale = get_user_locale();
+
+ if ( is_array( $utm ) ) {
+ if ( isset( $utm['source'] ) ) {
+ $source = $utm['source'];
+ }
+ if ( isset( $utm['medium'] ) ) {
+ $medium = $utm['medium'];
+ }
+ if ( isset( $utm['campaign'] ) ) {
+ $campaign = $utm['campaign'];
+ }
+ if ( isset( $utm['content'] ) ) {
+ $content = $utm['content'];
+ }
+ if ( isset( $utm['locale'] ) ) {
+ $locale = $utm['locale'];
+ }
+ } elseif ( is_string( $utm ) ) {
+ $content = $utm;
+ }
+
+ $query_args = [
+ 'utm_source' => esc_attr( rawurlencode( $source ) ),
+ 'utm_medium' => esc_attr( rawurlencode( $medium ) ),
+ 'utm_campaign' => esc_attr( rawurlencode( $campaign ) ),
+ 'utm_locale' => esc_attr( sanitize_key( $locale ) ),
+ ];
+
+ if ( ! empty( $content ) ) {
+ $query_args['utm_content'] = esc_attr( rawurlencode( $content ) );
+ }
+
+ return add_query_arg( $query_args, $url );
+ }
+
+ /**
+ * Whether the emailing functionality is blocked, with either an option or a constatnt.
+ *
+ * @since 1.7.0
+ *
+ * @return bool
+ */
+ public function is_blocked() {
+
+ return (bool) Options::init()->get( 'general', 'do_not_send' );
+ }
+
+ /**
+ * Whether the white-labeling is enabled.
+ * White-labeling disables the plugin "About us" page, it replaces any plugin marketing texts or images with
+ * white label ones.
+ *
+ * @since 2.0.0
+ *
+ * @return bool
+ */
+ public function is_white_labeled() {
+
+ return (bool) apply_filters( 'wp_mail_smtp_is_white_labeled', false );
+ }
+
+ /**
+ * Require the action scheduler in an early plugins_loaded hook (-10).
+ *
+ * @see https://actionscheduler.org/usage/#load-order
+ *
+ * @since 2.1.0
+ */
+ public function load_action_scheduler() {
+
+ require_once $this->plugin_path . '/vendor/woocommerce/action-scheduler/action-scheduler.php';
+ }
+
+ /**
+ * Get the list of all custom DB tables that should be present in the DB.
+ *
+ * @since 2.1.2
+ *
+ * @return array List of table names.
+ */
+ public function get_custom_db_tables() {
+
+ $tables = [
+ Meta::get_table_name(),
+ DebugEvents::get_table_name(),
+ ];
+
+ if ( $this->get_queue()->is_enabled() ) {
+ $tables[] = Queue::get_table_name();
+ }
+
+ return apply_filters( 'wp_mail_smtp_core_get_custom_db_tables', $tables );
+ }
+
+ /**
+ * Generate the correct MailCatcher object based on the PHPMailer version used in WP.
+ *
+ * Also conditionally require the needed class files.
+ *
+ * @see https://make.wordpress.org/core/2020/07/01/external-library-updates-in-wordpress-5-5-call-for-testing/
+ *
+ * @since 2.2.0
+ *
+ * @param bool $exceptions True if external exceptions should be thrown.
+ *
+ * @return MailCatcherInterface
+ */
+ public function generate_mail_catcher( $exceptions = null ) {
+
+ $is_old_version = version_compare( get_bloginfo( 'version' ), '5.5-alpha', '<' );
+
+ if ( $is_old_version ) {
+ if ( ! class_exists( '\PHPMailer', false ) ) {
+ require_once ABSPATH . WPINC . '/class-phpmailer.php';
+ }
+
+ $class_name = MailCatcher::class;
+ } else {
+ if ( ! class_exists( '\PHPMailer\PHPMailer\PHPMailer', false ) ) {
+ require_once ABSPATH . WPINC . '/PHPMailer/PHPMailer.php';
+ }
+
+ if ( ! class_exists( '\PHPMailer\PHPMailer\Exception', false ) ) {
+ require_once ABSPATH . WPINC . '/PHPMailer/Exception.php';
+ }
+
+ if ( ! class_exists( '\PHPMailer\PHPMailer\SMTP', false ) ) {
+ require_once ABSPATH . WPINC . '/PHPMailer/SMTP.php';
+ }
+
+ $class_name = MailCatcherV6::class;
+ }
+
+ /**
+ * Filters MailCatcher class name.
+ *
+ * @since 3.7.0
+ *
+ * @param string $mail_catcher The MailCatcher class name.
+ */
+ $class_name = apply_filters( 'wp_mail_smtp_core_generate_mail_catcher', $class_name );
+
+ $mail_catcher = new $class_name( $exceptions );
+
+ if ( $is_old_version ) {
+ $mail_catcher::$validator = static function ( $email ) {
+ return (bool) is_email( $email );
+ };
+ }
+
+ return $mail_catcher;
+ }
+
+ /**
+ * Check if the passed object is a valid PHPMailer object.
+ *
+ * @since 2.2.0
+ *
+ * @param object $phpmailer A potential PHPMailer object to be tested.
+ *
+ * @return bool
+ */
+ public function is_valid_phpmailer( $phpmailer ) {
+
+ return $phpmailer instanceof MailCatcherInterface ||
+ $phpmailer instanceof \PHPMailer ||
+ $phpmailer instanceof \PHPMailer\PHPMailer\PHPMailer;
+ }
+
+ /**
+ * Force the `mail.from_email_force` plugin option to always return true if the current saved mailer is Gmail.
+ * Alters the plugin options retrieving via the Options::get method.
+ *
+ * The gmail mailer check is performed when this filter is added.
+ *
+ * @deprecated 2.7.0
+ *
+ * @since 2.2.0
+ *
+ * @param mixed $value The value of the plugin option that is being retrieved via Options::get method.
+ * @param string $group The group of the plugin option that is being retrieved via Options::get method.
+ * @param string $key The key of the plugin option that is being retrieved via Options::get method.
+ *
+ * @return mixed
+ */
+ public function gmail_mailer_get_from_email_force( $value, $group, $key ) {
+
+ _deprecated_function( __METHOD__, '2.7.0' );
+
+ if ( $group === 'mail' && $key === 'from_email_force' ) {
+ $value = true;
+ }
+
+ return $value;
+ }
+
+ /**
+ * Load the plugin admin bar menu and initialize it.
+ *
+ * @since 2.3.0
+ *
+ * @return AdminBarMenu
+ */
+ public function get_admin_bar_menu() {
+
+ static $admin_bar_menu;
+
+ if ( ! isset( $admin_bar_menu ) ) {
+ $admin_bar_menu = apply_filters(
+ 'wp_mail_smtp_core_get_admin_bar_menu',
+ new AdminBarMenu()
+ );
+
+ if ( method_exists( $admin_bar_menu, 'init' ) ) {
+ $admin_bar_menu->init();
+ }
+ }
+
+ return $admin_bar_menu;
+ }
+
+ /**
+ * Load the plugin usage tracking.
+ *
+ * @since 2.3.0
+ *
+ * @return UsageTracking
+ */
+ public function get_usage_tracking() {
+
+ static $usage_tracking;
+
+ if ( ! isset( $usage_tracking ) ) {
+ $usage_tracking = apply_filters( 'wp_mail_smtp_core_get_usage_tracking', new UsageTracking() );
+
+ if ( method_exists( $usage_tracking, 'load' ) ) {
+ add_action( 'after_setup_theme', [ $usage_tracking, 'load' ] );
+ }
+ }
+
+ return $usage_tracking;
+ }
+
+ /**
+ * Load the plugin admin notifications functionality and initializes it.
+ *
+ * @since 2.3.0
+ *
+ * @return Notifications
+ */
+ public function get_notifications() {
+
+ static $notifications;
+
+ if ( ! isset( $notifications ) ) {
+ $notifications = apply_filters(
+ 'wp_mail_smtp_core_get_notifications',
+ new Notifications()
+ );
+
+ if ( method_exists( $notifications, 'init' ) ) {
+ $notifications->init();
+ }
+ }
+
+ return $notifications;
+ }
+
+ /**
+ * Prepare the HTML output for a plugin loader/spinner.
+ *
+ * @since 2.4.0
+ *
+ * @param string $color The color of the loader ('', 'blue' or 'white'), where '' is default orange.
+ * @param string $size The size of the loader ('lg', 'md', 'sm').
+ *
+ * @return string
+ */
+ public function prepare_loader( $color = '', $size = 'md' ) {
+
+ $svg_name = 'loading';
+
+ if ( in_array( $color, [ 'blue', 'white' ], true ) ) {
+ $svg_name .= '-' . $color;
+ }
+
+ if ( ! in_array( $size, [ 'lg', 'md', 'sm' ], true ) ) {
+ $size = 'md';
+ }
+
+ return '';
+ }
+
+ /**
+ * Initialize the Connect functionality.
+ * This has to execute after pro was loaded, since we need check for plugin license type (if pro or not).
+ * That's why it's hooked to the same WP hook (`plugins_loaded`) as `get_pro` with lower priority.
+ *
+ * @since 2.6.0
+ */
+ public function get_connect() {
+
+ static $connect;
+
+ if ( ! isset( $connect ) && ! $this->is_pro() ) {
+ $connect = apply_filters( 'wp_mail_smtp_core_get_connect', new Connect() );
+
+ if ( method_exists( $connect, 'hooks' ) ) {
+ $connect->hooks();
+ }
+ }
+
+ return $connect;
+ }
+
+ /**
+ * Load the plugin compatibility functionality and initializes it.
+ *
+ * @since 2.8.0
+ *
+ * @return Compatibility
+ */
+ public function get_compatibility() {
+
+ static $compatibility;
+
+ if ( ! isset( $compatibility ) ) {
+
+ /**
+ * Filters compatibility instance.
+ *
+ * @since 2.8.0
+ *
+ * @param \WPMailSMTP\Compatibility\Compatibility $compatibility Compatibility instance.
+ */
+ $compatibility = apply_filters( 'wp_mail_smtp_core_get_compatibility', new Compatibility() );
+
+ if ( method_exists( $compatibility, 'init' ) ) {
+ $compatibility->init();
+ }
+ }
+
+ return $compatibility;
+ }
+
+ /**
+ * Get the Dashboard Widget object (lite or pro version).
+ *
+ * @since 2.9.0
+ *
+ * @return DashboardWidget
+ */
+ public function get_dashboard_widget() {
+
+ static $dashboard_widget;
+
+ if ( ! isset( $dashboard_widget ) ) {
+
+ /**
+ * Filter the dashboard widget class name.
+ *
+ * @since 2.9.0
+ *
+ * @param DashboardWidget $class_name The dashboard widget class name to be instantiated.
+ */
+ $class_name = apply_filters( 'wp_mail_smtp_core_get_dashboard_widget', DashboardWidget::class );
+ $dashboard_widget = new $class_name();
+
+ if ( method_exists( $dashboard_widget, 'init' ) ) {
+ $dashboard_widget->init();
+ }
+ }
+
+ return $dashboard_widget;
+ }
+
+ /**
+ * Get the reports object (lite or pro version).
+ *
+ * @since 3.0.0
+ *
+ * @return Reports
+ */
+ public function get_reports() {
+
+ static $reports;
+
+ if ( ! isset( $reports ) ) {
+
+ /**
+ * Filter the reports class name.
+ *
+ * @since 3.0.0
+ *
+ * @param Reports $class_name The reports class name to be instantiated.
+ */
+ $class_name = apply_filters( 'wp_mail_smtp_core_get_reports', Reports::class );
+ $reports = new $class_name();
+
+ if ( method_exists( $reports, 'init' ) ) {
+ $reports->init();
+ }
+ }
+
+ return $reports;
+ }
+
+ /**
+ * Get the DBRepair object (lite or pro version).
+ *
+ * @since 3.6.0
+ *
+ * @return DBRepair
+ */
+ public function get_db_repair() {
+
+ static $db_repair;
+
+ if ( ! isset( $db_repair ) ) {
+
+ /**
+ * Filter the DBRepair class name.
+ *
+ * @since 3.6.0
+ *
+ * @param DBRepair $class_name The reports class name to be instantiated.
+ */
+ $class_name = apply_filters( 'wp_mail_smtp_core_get_db_repair', DBRepair::class );
+ $db_repair = new $class_name();
+
+ if ( method_exists( $db_repair, 'hooks' ) ) {
+ $db_repair->hooks();
+ }
+ }
+
+ return $db_repair;
+ }
+
+ /**
+ * Get connections manager.
+ *
+ * @since 3.7.0
+ *
+ * @return ConnectionsManager
+ */
+ public function get_connections_manager() {
+
+ static $connections_manager = null;
+
+ if ( is_null( $connections_manager ) ) {
+
+ /**
+ * Filter the connections manager class name.
+ *
+ * @since 3.7.0
+ *
+ * @param ConnectionsManager $connections_manager The connections manager class name to be instantiated.
+ */
+ $class_name = apply_filters( 'wp_mail_smtp_core_get_connections_manager', ConnectionsManager::class );
+ $connections_manager = new $class_name();
+
+ if ( method_exists( $connections_manager, 'hooks' ) ) {
+ $connections_manager->hooks();
+ }
+ }
+
+ return $connections_manager;
+ }
+
+ /**
+ * Get the `wp_mail` function initiator.
+ *
+ * @since 3.7.0
+ *
+ * @return WPMailInitiator
+ */
+ public function get_wp_mail_initiator() {
+
+ static $wp_mail_initiator = null;
+
+ if ( is_null( $wp_mail_initiator ) ) {
+
+ /**
+ * Filter the `wp_mail` function initiator class name.
+ *
+ * @since 3.7.0
+ *
+ * @param WPMailInitiator $wp_mail_initiator The `wp_mail` function initiator class name to be instantiated.
+ */
+ $class_name = apply_filters( 'wp_mail_smtp_core_get_wp_mail_initiator', WPMailInitiator::class );
+ $wp_mail_initiator = new $class_name();
+
+ if ( method_exists( $wp_mail_initiator, 'hooks' ) ) {
+ $wp_mail_initiator->hooks();
+ }
+ }
+
+ return $wp_mail_initiator;
+ }
+
+ /**
+ * Detect incorrect `wp_mail` function location and display warning.
+ *
+ * @since 3.5.0
+ */
+ private function wp_mail_function_incorrect_location_notice() { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh
+
+ /**
+ * Filters whether to display incorrect `wp_mail` function location warning.
+ *
+ * @since 3.5.0
+ *
+ * @param bool $display Whether to display incorrect `wp_mail` function location warning.
+ */
+ $display_notice = apply_filters( 'wp_mail_smtp_core_wp_mail_function_incorrect_location_notice', true );
+
+ if ( ! $display_notice || ! defined( 'ABSPATH' ) || ! defined( 'WPINC' ) ) {
+ return;
+ }
+
+ try {
+ $wp_mail_reflection = new ReflectionFunction( 'wp_mail' );
+ $wp_mail_filepath = $wp_mail_reflection->getFileName();
+ $separator = defined( 'DIRECTORY_SEPARATOR' ) ? DIRECTORY_SEPARATOR : '/';
+
+ $wp_mail_original_filepath = ABSPATH . WPINC . $separator . 'pluggable.php';
+
+ if ( str_replace( '\\', '/', $wp_mail_filepath ) === str_replace( '\\', '/', $wp_mail_original_filepath ) ) {
+ return;
+ }
+
+ if ( strpos( $wp_mail_filepath, WPINC . $separator . 'pluggable.php' ) !== false ) {
+ return;
+ }
+
+ $conflict = WP::get_initiator( $wp_mail_filepath );
+
+ $message = esc_html__( 'WP Mail SMTP has detected incorrect "wp_mail" function location. Usually, this means that emails will not be sent successfully!', 'wp-mail-smtp' );
+
+ if ( $conflict['type'] === 'plugin' ) {
+ $message .= '
' . sprintf(
+ /* translators: %s - plugin name. */
+ esc_html__( 'It looks like the "%s" plugin is overwriting the "wp_mail" function. Please reach out to the plugin developer on how to disable or remove the "wp_mail" function overwrite to prevent conflicts with WP Mail SMTP.', 'wp-mail-smtp' ),
+ esc_html( $conflict['name'] )
+ );
+ } elseif ( $conflict['type'] === 'mu-plugin' ) {
+ $message .= '
' . sprintf(
+ /* translators: %s - must-use plugin name. */
+ esc_html__( 'It looks like the "%s" must-use plugin is overwriting the "wp_mail" function. Please reach out to your hosting provider on how to disable or remove the "wp_mail" function overwrite to prevent conflicts with WP Mail SMTP.', 'wp-mail-smtp' ),
+ esc_html( $conflict['name'] )
+ );
+ } elseif ( $wp_mail_filepath === ABSPATH . 'wp-config.php' ) {
+ $message .= '
' . esc_html__( 'It looks like it\'s overwritten in the "wp-config.php" file. Please reach out to your hosting provider on how to disable or remove the "wp_mail" function overwrite to prevent conflicts with WP Mail SMTP.', 'wp-mail-smtp' );
+ }
+
+ $message .= '
+ CustomHeader; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
+ }
+
+ /**
+ * Get the PHPMailer line ending.
+ *
+ * @since 2.2.0
+ *
+ * @return string
+ */
+ public function get_line_ending() {
+
+ return $this->LE; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
+ }
+
+ /**
+ * Throw PHPMailer exception.
+ *
+ * @since 4.0.0
+ *
+ * @param string $error Error message.
+ *
+ * @throws phpmailerException PHPMailer exception.
+ */
+ protected function throw_exception( $error ) {
+
+ throw new phpmailerException( $error );
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/src/MailCatcherInterface.php b/wp-content/plugins/wp-mail-smtp/src/MailCatcherInterface.php
new file mode 100755
index 00000000..bf369f34
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/src/MailCatcherInterface.php
@@ -0,0 +1,69 @@
+debug_event_id = false;
+ $this->is_test_email = false;
+ $this->is_setup_wizard_test_email = false;
+ $this->is_emailing_blocked = false;
+ $this->latest_error = '';
+
+ if ( wp_mail_smtp()->is_blocked() ) {
+ $this->is_emailing_blocked = true;
+ }
+
+ // Always allow a test email - check for the specific header.
+ foreach ( (array) $this->getCustomHeaders() as $header ) {
+ if (
+ ! empty( $header[0] ) &&
+ ! empty( $header[1] ) &&
+ $header[0] === 'X-Mailer-Type'
+ ) {
+ if ( trim( $header[1] ) === 'WPMailSMTP/Admin/Test' ) {
+ $this->is_emailing_blocked = false;
+ $this->is_test_email = true;
+ } elseif ( trim( $header[1] ) === 'WPMailSMTP/Admin/SetupWizard/Test' ) {
+ $this->is_setup_wizard_test_email = true;
+ }
+ }
+ }
+
+ // Log blocked emails if the option is enabled.
+ if ( $this->is_emailing_blocked ) {
+ /**
+ * Fires when an email is blocked from being sent.
+ *
+ * @since 4.5.0
+ *
+ * @param MailCatcherInterface $mailcatcher The MailCatcher object.
+ */
+ do_action( 'wp_mail_smtp_mail_catcher_send_blocked', $this );
+
+ return false;
+ }
+
+ // If it's not a test email,
+ // check if the email should be enqueued
+ // instead of being sent immediately.
+ if ( ! $this->is_test_email && ! $this->is_setup_wizard_test_email ) {
+
+ /**
+ * Filters whether an email should be enqueued or sent immediately.
+ *
+ * @since 4.0.0
+ *
+ * @param bool $should_enqueue Whether to enqueue an email, or send it.
+ * @param array $wp_mail_args Original arguments of the `wp_mail` call.
+ */
+ $should_enqueue_email = apply_filters(
+ 'wp_mail_smtp_mail_catcher_send_enqueue_email',
+ false,
+ wp_mail_smtp()->get_processor()->get_filtered_wp_mail_args()
+ );
+
+ $queue = wp_mail_smtp()->get_queue();
+
+ // If we should enqueue the email,
+ // and the email has been enqueued,
+ // bail.
+ if ( $should_enqueue_email && $queue->enqueue_email() ) {
+ return true;
+ }
+ }
+
+ $connection = wp_mail_smtp()->get_connections_manager()->get_mail_connection();
+ $mailer_slug = $connection->get_mailer_slug();
+
+ // Define a custom header, that will be used to identify the plugin and the mailer.
+ // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
+ $this->XMailer = 'WPMailSMTP/Mailer/' . $mailer_slug . ' ' . WPMS_PLUGIN_VER;
+
+ // Use the default PHPMailer, as we inject our settings there for certain providers.
+ if (
+ $mailer_slug === 'mail' ||
+ $mailer_slug === 'smtp' ||
+ $mailer_slug === 'pepipost'
+ ) {
+ return $this->smtp_send( $connection );
+ } else {
+ return $this->api_send( $connection );
+ }
+ }
+
+ /**
+ * Send email via SMTP.
+ *
+ * @since 4.0.0
+ *
+ * @param ConnectionInterface $connection The connection object.
+ *
+ * @throws Exception When sending via PhpMailer fails for some reason.
+ *
+ * @return bool
+ */
+ private function smtp_send( $connection ) { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh
+
+ $mailer_slug = $connection->get_mailer_slug();
+
+ // phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
+ try {
+ if ( DebugEvents::is_debug_enabled() && ! $this->is_test_email ) {
+ $this->SMTPDebug = 3;
+ $this->Debugoutput = [ $this, 'debug_output_callback' ];
+ }
+
+ /**
+ * Fires before email pre send via SMTP.
+ *
+ * Allow to hook early to catch any early failed emails.
+ *
+ * @since 2.9.0
+ *
+ * @param MailCatcherInterface $mailcatcher The MailCatcher object.
+ */
+ do_action( 'wp_mail_smtp_mailcatcher_smtp_pre_send_before', $this );
+
+ // Prepare all the headers.
+ if ( ! $this->preSend() ) {
+ $this->throw_exception( $this->ErrorInfo );
+ }
+
+ /**
+ * Fires before email send via SMTP.
+ *
+ * Allow to hook after all the preparation before the actual sending.
+ *
+ * @since 2.9.0
+ *
+ * @param MailCatcherInterface $mailcatcher The MailCatcher object.
+ */
+ do_action( 'wp_mail_smtp_mailcatcher_smtp_send_before', $this );
+
+ if ( ! $this->postSend() ) {
+ $this->throw_exception( $this->ErrorInfo );
+ }
+
+ DebugEvents::add_debug(
+ esc_html__( 'An email request was sent.', 'wp-mail-smtp' )
+ );
+
+ return true;
+ } catch ( Exception $e ) {
+ $this->mailHeader = '';
+
+ // We need this to append SMTP error to the `PHPMailer::ErrorInfo` property.
+ $this->setError( $e->getMessage() );
+
+ // Set the debug error, but not for default PHP mailer.
+ if ( $mailer_slug !== 'mail' ) {
+ $error_message = 'Mailer: ' . esc_html( wp_mail_smtp()->get_providers()->get_options( $mailer_slug )->get_title() ) . "\r\n" . $this->ErrorInfo;
+
+ $this->debug_event_id = Debug::set( $error_message );
+ $this->latest_error = $error_message;
+
+ if ( DebugEvents::is_debug_enabled() && ! empty( $this->debug_output_buffer ) ) {
+ $debug_message = $error_message . "\r\n" . esc_html__( 'Debug Output:', 'wp-mail-smtp' ) . "\r\n";
+ $debug_message .= implode( "\r\n", $this->debug_output_buffer );
+
+ $this->debug_event_id = DebugEvents::add_debug( $debug_message );
+ }
+ }
+
+ /**
+ * Fires after email sent failure via SMTP.
+ *
+ * @since 3.5.0
+ *
+ * @param string $error_message Error message.
+ * @param MailCatcherInterface $mailcatcher The MailCatcher object.
+ * @param string $mailer_slug Current mailer name.
+ */
+ do_action( 'wp_mail_smtp_mailcatcher_send_failed', $this->ErrorInfo, $this, $mailer_slug );
+
+ if ( $this->exceptions ) {
+ throw $e;
+ }
+
+ return false;
+ } finally {
+
+ // Clear debug output buffer.
+ $this->debug_output_buffer = [];
+ }
+ // phpcs:enable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
+ }
+
+ /**
+ * Send email via API integration.
+ *
+ * @since 4.0.0
+ *
+ * @param ConnectionInterface $connection The connection object.
+ *
+ * @throws Exception When sending fails for some reason.
+ *
+ * @return bool
+ */
+ private function api_send( $connection ) { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh
+
+ $mailer_slug = $connection->get_mailer_slug();
+
+ // phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
+ try {
+ // We need this so that the \PHPMailer class will correctly prepare all the headers.
+ $this->Mailer = 'mail';
+
+ /**
+ * Fires before email pre send.
+ *
+ * Allow to hook early to catch any early failed emails.
+ *
+ * @since 2.9.0
+ *
+ * @param MailCatcherInterface $mailcatcher The MailCatcher object.
+ */
+ do_action( 'wp_mail_smtp_mailcatcher_pre_send_before', $this );
+
+ // Prepare everything (including the message) for sending.
+ if ( ! $this->preSend() ) {
+ $this->throw_exception( $this->ErrorInfo );
+ }
+
+ $mailer = wp_mail_smtp()->get_providers()->get_mailer( $mailer_slug, $this, $connection );
+
+ if ( ! $mailer ) {
+ $this->throw_exception( esc_html__( 'The selected mailer not found.', 'wp-mail-smtp' ) );
+ }
+
+ if ( ! $mailer->is_php_compatible() ) {
+ $this->throw_exception( esc_html__( 'The selected mailer is not compatible with your PHP version.', 'wp-mail-smtp' ) );
+ }
+
+ /**
+ * Fires before email send.
+ *
+ * Allows to hook after all the preparation before the actual sending.
+ *
+ * @since 3.3.0
+ *
+ * @param MailerAbstract $mailer The Mailer object.
+ */
+ do_action( 'wp_mail_smtp_mailcatcher_send_before', $mailer );
+
+ /*
+ * Send the actual email.
+ * We reuse everything, that was preprocessed for usage in \PHPMailer.
+ */
+ $mailer->send();
+
+ $is_sent = $mailer->is_email_sent();
+
+ /**
+ * Fires after email send.
+ *
+ * Allow to perform any actions with the data.
+ *
+ * @since 3.5.0
+ *
+ * @param MailerAbstract $mailer The Mailer object.
+ * @param MailCatcherInterface $mailcatcher The MailCatcher object.
+ */
+ do_action( 'wp_mail_smtp_mailcatcher_send_after', $mailer, $this );
+
+ if ( $is_sent !== true ) {
+ $this->throw_exception( $mailer->get_response_error() );
+ }
+
+ // Clear debug messages if email is successfully sent.
+ Debug::clear();
+
+ return true;
+ } catch ( Exception $e ) {
+ // Add mailer to the beginning and save to display later.
+ $message = 'Mailer: ' . esc_html( wp_mail_smtp()->get_providers()->get_options( $mailer_slug )->get_title() ) . "\r\n";
+
+ $conflicts = new Conflicts();
+
+ if ( $conflicts->is_detected() ) {
+ $conflict_plugin_names = implode( ', ', $conflicts->get_all_conflict_names() );
+ $message .= 'Conflicts: ' . esc_html( $conflict_plugin_names ) . "\r\n";
+ }
+
+ $error_message = $message . $e->getMessage();
+ $this->debug_event_id = Debug::set( $error_message );
+ $this->latest_error = $error_message;
+
+ /**
+ * Fires after email sent failure.
+ *
+ * @since 3.5.0
+ *
+ * @param string $error_message Error message.
+ * @param MailCatcherInterface $mailcatcher The MailCatcher object.
+ * @param string $mailer_slug Current mailer name.
+ */
+ do_action( 'wp_mail_smtp_mailcatcher_send_failed', $e->getMessage(), $this, $mailer_slug );
+
+ if ( $this->exceptions ) {
+ throw $e;
+ }
+
+ return false;
+ }
+ // phpcs:enable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
+ }
+
+ /**
+ * Create a unique ID to use for multipart email boundaries.
+ *
+ * @since 2.4.0
+ *
+ * @return string
+ */
+ public function generate_id() {
+
+ return $this->generateId();
+ }
+
+ /**
+ * Debug output callback.
+ * Save debugging info to buffer array.
+ *
+ * @since 3.3.0
+ *
+ * @param string $str Message.
+ * @param int $level Debug level.
+ */
+ public function debug_output_callback( $str, $level ) {
+
+ /*
+ * Filter out all higher levels than 3.
+ * SMTPDebug level 3 is commands, data and connection status.
+ */
+ if ( $level > 3 ) {
+ return;
+ }
+
+ $this->debug_output_buffer[] = trim( $str, "\r\n" );
+ }
+
+ /**
+ * Get debug event ID.
+ *
+ * @since 3.5.0
+ *
+ * @return bool|int
+ */
+ public function get_debug_event_id() {
+
+ return $this->debug_event_id;
+ }
+
+ /**
+ * Whether the current email is a test email.
+ *
+ * @since 3.5.0
+ *
+ * @return bool
+ */
+ public function is_test_email() {
+
+ return $this->is_test_email;
+ }
+
+ /**
+ * Whether the current email is a Setup Wizard test email.
+ *
+ * @since 3.5.0
+ *
+ * @return bool
+ */
+ public function is_setup_wizard_test_email() {
+
+ return $this->is_setup_wizard_test_email;
+ }
+
+ /**
+ * Whether the current email is blocked to be sent.
+ *
+ * @since 3.8.0
+ *
+ * @return bool
+ */
+ public function is_emailing_blocked() {
+
+ return $this->is_emailing_blocked;
+ }
+
+ /**
+ * Return the list of properties representing
+ * this class' state.
+ *
+ * @since 4.0.0
+ *
+ * @return array State of this class.
+ */
+ private function get_state_properties() {
+
+ return [
+ 'CharSet',
+ 'ContentType',
+ 'Encoding',
+ 'CustomHeader',
+ 'Subject',
+ 'Body',
+ 'AltBody',
+ 'ReplyTo',
+ 'to',
+ 'cc',
+ 'bcc',
+ 'attachment',
+ ];
+ }
+
+ /**
+ * Return an array of relevant properties.
+ *
+ * @since 4.0.0
+ *
+ * @return array State of this class.
+ */
+ public function get_state() {
+
+ $state = [];
+
+ foreach ( $this->get_state_properties() as $property ) {
+ $state[ $property ] = $this->{$property};
+ }
+
+ return $state;
+ }
+
+ /**
+ * Set properties from a provided array of data.
+ *
+ * @since 4.0.0
+ *
+ * @param array $state Array of properties to apply.
+ */
+ public function set_state( $state ) { // phpcs:ignore Generic.Metrics.NestingLevel.MaxExceeded
+
+ // Filter out non-allowed properties.
+ $state = array_intersect_key(
+ $state,
+ array_flip( $this->get_state_properties() )
+ );
+
+ foreach ( $state as $property => $value ) {
+ if ( $property !== 'attachment' ) {
+ $this->{$property} = $value;
+ } else {
+ // Handle potential I/O exceptions
+ // in PHPMailer when attaching files.
+ $this->clearAttachments();
+
+ foreach ( $state['attachment'] as $attachment ) {
+ [ $path, , $name ] = $attachment;
+
+ try {
+ $this->addAttachment( $path, $name );
+ } catch ( Exception $e ) {
+ continue;
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Set the From and FromName properties.
+ *
+ * @since 4.7.1
+ *
+ * @param string $address Email address.
+ * @param string $name Name.
+ * @param bool $auto Whether to also set the Sender address, defaults to true.
+ *
+ * @return bool Returns true on success and false on failure.
+ */
+ public function setFrom( $address, $name = '', $auto = true ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid
+
+ // Set `$auto` param as false, to control return-path via plugin settings.
+ return parent::setFrom( $address, $name, false );
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/src/MailCatcherV6.php b/wp-content/plugins/wp-mail-smtp/src/MailCatcherV6.php
new file mode 100755
index 00000000..f07bcb85
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/src/MailCatcherV6.php
@@ -0,0 +1,66 @@
+maybe_migrate();
+ }
+
+ /**
+ * Static on purpose, to get current migration version without __construct() and validation.
+ *
+ * @since 2.1.0
+ *
+ * @return int
+ */
+ public static function get_cur_version() {
+
+ return (int) get_option( static::OPTION_NAME, 0 );
+ }
+
+ /**
+ * Run the migration if needed.
+ *
+ * @since 2.1.0
+ */
+ protected function maybe_migrate() {
+
+ if ( version_compare( $this->cur_ver, static::VERSION, '<' ) ) {
+ $this->run( static::VERSION );
+ }
+ }
+
+ /**
+ * Actual migration launcher.
+ *
+ * @since 2.1.0
+ *
+ * @param int $version The version of migration to run.
+ */
+ protected function run( $version ) {
+
+ $function_version = (int) $version;
+
+ if ( method_exists( $this, 'migrate_to_' . $function_version ) ) {
+ $this->{'migrate_to_' . $function_version}();
+ } else {
+ if ( WP::in_wp_admin() ) {
+ $message = sprintf( /* translators: %1$s - WP Mail SMTP, %2$s - error message. */
+ esc_html__( 'There was an error while upgrading the database. Please contact %1$s support with this information: %2$s.', 'wp-mail-smtp' ),
+ 'WP Mail SMTP',
+ 'migration from v' . static::get_cur_version() . ' to v' . static::VERSION . ' failed. Plugin version: v' . WPMS_PLUGIN_VER . ''
+ );
+
+ WP::add_admin_notice( $message, WP::ADMIN_NOTICE_ERROR );
+ }
+ }
+ }
+
+ /**
+ * Update migration version in options table.
+ *
+ * @since 2.1.0
+ *
+ * @param int $version Migration version.
+ */
+ protected function update_db_ver( $version = 0 ) {
+
+ if ( empty( $version ) ) {
+ $version = static::VERSION;
+ }
+
+ // Autoload it, because this value is checked all the time
+ // and no need to request it separately from all autoloaded options.
+ update_option( static::OPTION_NAME, $version, true );
+ }
+
+ /**
+ * Prevent running the same migration twice.
+ * Run migration only when required.
+ *
+ * @since 2.1.0
+ *
+ * @param string $version The version of migration to check for potential execution.
+ */
+ protected function maybe_required_older_migrations( $version ) {
+
+ if ( version_compare( $this->cur_ver, $version, '<' ) ) {
+ $this->run( $version );
+ }
+ }
+
+ /**
+ * Migration from 0.x to 1.0.0.
+ * Move separate plugin WP options to one main plugin WP option setting.
+ *
+ * @since 2.1.0
+ */
+ private function migrate_to_1() {
+
+ if ( $this->is_migrated() ) {
+ return;
+ }
+
+ $this->old_values = $this->get_old_values();
+ $this->new_values = $this->get_converted_options();
+
+ Options::init()->set( $this->new_values, true );
+
+ $this->update_db_ver( 1 );
+ }
+
+ /**
+ * Migration from 1.x to 2.1.0.
+ * Create Tasks\Meta table, if it does not exist.
+ *
+ * @since 2.1.0
+ */
+ private function migrate_to_2() {
+
+ $this->maybe_required_older_migrations( 1 );
+
+ $meta = new Meta();
+
+ // Create the table if it doesn't exist.
+ if ( $meta && ! $meta->table_exists() ) {
+ $meta->create_table();
+ }
+
+ $this->update_db_ver( 2 );
+ }
+
+ /**
+ * Migration to 2.6.0.
+ * Cancel all recurring ActionScheduler tasks, so they will be newly created and no longer
+ * cause PHP fatal error on PHP 8 (because of the named parameter 'tasks_meta_id').
+ *
+ * @since 2.6.0
+ */
+ private function migrate_to_3() {
+
+ $this->maybe_required_older_migrations( 2 );
+
+ $tasks = [];
+ $ut = new UsageTracking\UsageTracking();
+
+ if ( $ut->is_enabled() ) {
+ $tasks[] = '\WPMailSMTP\UsageTracking\SendUsageTask';
+ }
+
+ $recurring_tasks = apply_filters( 'wp_mail_smtp_migration_cancel_recurring_tasks', $tasks );
+
+ foreach ( $recurring_tasks as $task ) {
+ ( new $task() )->cancel();
+ }
+
+ $this->update_db_ver( 3 );
+ }
+
+ /**
+ * Migration to 3.0.0.
+ * Disable summary report email for Lite users and Multisite installations after update.
+ * For new installations we have default values in Options::get_defaults.
+ *
+ * @since 3.0.0
+ */
+ protected function migrate_to_4() {
+
+ $this->maybe_required_older_migrations( 3 );
+
+ $options = Options::init();
+
+ $value = $options->get( 'general', SummaryReportEmail::SETTINGS_SLUG );
+
+ // If option was not already set, then plugin was updated from lower version.
+ if (
+ ( $value === '' || $value === null ) &&
+ ( is_multisite() || ! wp_mail_smtp()->is_pro() )
+ ) {
+ $data = [
+ 'general' => [
+ SummaryReportEmail::SETTINGS_SLUG => true,
+ ],
+ ];
+
+ $options->set( $data, false, false );
+
+ // Just to be safe cancel summary report email task.
+ ( new SummaryReportEmailTask() )->cancel();
+ }
+
+ $this->update_db_ver( 4 );
+ }
+
+ /**
+ * Cleanup scheduled actions meta table.
+ *
+ * @since 3.5.0
+ */
+ protected function migrate_to_5() {
+
+ $this->maybe_required_older_migrations( 4 );
+
+ global $wpdb;
+
+ $meta = new Meta();
+
+ if (
+ $meta->table_exists() &&
+ $meta->table_exists( $wpdb->prefix . 'actionscheduler_actions' ) &&
+ $meta->table_exists( $wpdb->prefix . 'actionscheduler_groups' )
+ ) {
+ $group = Tasks::GROUP;
+ $sql = "SELECT DISTINCT a.args FROM {$wpdb->prefix}actionscheduler_actions a
+ JOIN {$wpdb->prefix}actionscheduler_groups g ON g.group_id = a.group_id
+ WHERE g.slug = '$group' AND a.status IN ('pending', 'in-progress')";
+
+ // phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared
+ $results = $wpdb->get_results( $sql, 'ARRAY_A' );
+ // phpcs:enable WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared
+
+ $results = $results ? $results : [];
+ $meta_ids = [];
+
+ foreach ( $results as $result ) {
+ $args = isset( $result['args'] ) ? json_decode( $result['args'], true ) : null;
+
+ if ( $args && isset( $args[0] ) && is_numeric( $args[0] ) ) {
+ $meta_ids[] = $args[0];
+ }
+ }
+
+ $table = Meta::get_table_name();
+ $not_in = 0;
+
+ if ( ! empty( $meta_ids ) ) {
+ // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
+ $not_in = $wpdb->prepare( implode( ',', array_fill( 0, count( $meta_ids ), '%d' ) ), $meta_ids );
+ }
+
+ // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.NoCaching
+ $wpdb->query( "DELETE FROM $table WHERE id NOT IN ($not_in)" );
+ // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.NoCaching
+ }
+
+ // Save the current version to DB.
+ $this->update_db_ver( 5 );
+ }
+
+ /**
+ * Whether we already migrated or not.
+ *
+ * @since 1.0.0
+ *
+ * @return bool
+ */
+ protected function is_migrated() {
+
+ $is_migrated = false;
+ $new_values = get_option( Options::META_KEY, array() );
+
+ if ( ! empty( $new_values ) ) {
+ $is_migrated = true;
+ }
+
+ return $is_migrated;
+ }
+
+ /**
+ * Get all old values from DB.
+ *
+ * @since 1.0.0
+ *
+ * @return array
+ */
+ protected function get_old_values() {
+
+ $old_values = array();
+
+ foreach ( $this->old_keys as $old_key ) {
+ $value = get_option( $old_key, '' );
+
+ if ( ! empty( $value ) ) {
+ $old_values[ $old_key ] = $value;
+ }
+ }
+
+ return $old_values;
+ }
+
+ /**
+ * Convert old values from key=>value to a multidimensional array of data.
+ *
+ * @since 1.0.0
+ */
+ protected function get_converted_options() {
+
+ $converted = array();
+
+ foreach ( $this->old_keys as $old_key ) {
+
+ $old_value = isset( $this->old_values[ $old_key ] ) ? $this->old_values[ $old_key ] : '';
+
+ switch ( $old_key ) {
+ case 'pepipost_user':
+ case 'pepipost_pass':
+ case 'pepipost_port':
+ case 'pepipost_ssl':
+ // Do not migrate pepipost options if it's not activated at the moment.
+ if ( isset( $this->old_values['mailer'] ) && $this->old_values['mailer'] === 'pepipost' ) {
+ $shortcut = explode( '_', $old_key );
+
+ if ( $old_key === 'pepipost_ssl' ) {
+ $converted[ $shortcut[0] ]['encryption'] = $old_value;
+ } else {
+ $converted[ $shortcut[0] ][ $shortcut[1] ] = $old_value;
+ }
+ }
+ break;
+
+ case 'smtp_host':
+ case 'smtp_port':
+ case 'smtp_ssl':
+ case 'smtp_auth':
+ case 'smtp_user':
+ case 'smtp_pass':
+ $shortcut = explode( '_', $old_key );
+
+ if ( $old_key === 'smtp_ssl' ) {
+ $converted[ $shortcut[0] ]['encryption'] = $old_value;
+ } elseif ( $old_key === 'smtp_auth' ) {
+ $converted[ $shortcut[0] ][ $shortcut[1] ] = ( $old_value === 'true' ? 'yes' : 'no' );
+ } else {
+ $converted[ $shortcut[0] ][ $shortcut[1] ] = $old_value;
+ }
+
+ break;
+
+ case 'mail_from':
+ $converted['mail']['from_email'] = $old_value;
+ break;
+ case 'mail_from_name':
+ $converted['mail']['from_name'] = $old_value;
+ break;
+ case 'mail_set_return_path':
+ $converted['mail']['return_path'] = ( $old_value === 'true' );
+ break;
+ case 'mailer':
+ $converted['mail']['mailer'] = ! empty( $old_value ) ? $old_value : 'mail';
+ break;
+ case 'wp_mail_smtp_am_notifications_hidden':
+ $converted['general']['am_notifications_hidden'] = ( isset( $old_value ) && $old_value === 'true' );
+ break;
+ }
+ }
+
+ $converted = $this->get_converted_constants_options( $converted );
+
+ return $converted;
+ }
+
+ /**
+ * Some users use constants in wp-config.php to define values.
+ * We need to prioritize them and reapply data to options.
+ * Use only those that are actually defined.
+ *
+ * @since 1.0.0
+ *
+ * @param array $converted
+ *
+ * @return array
+ */
+ protected function get_converted_constants_options( $converted ) {
+
+ // Are we configured via constants?
+ if ( ! defined( 'WPMS_ON' ) || ! WPMS_ON ) {
+ return $converted;
+ }
+
+ /*
+ * Mail settings.
+ */
+ if ( defined( 'WPMS_MAIL_FROM' ) ) {
+ $converted['mail']['from_email'] = WPMS_MAIL_FROM;
+ }
+ if ( defined( 'WPMS_MAIL_FROM_NAME' ) ) {
+ $converted['mail']['from_name'] = WPMS_MAIL_FROM_NAME;
+ }
+ if ( defined( 'WPMS_MAILER' ) ) {
+ $converted['mail']['mailer'] = WPMS_MAILER;
+ }
+ if ( defined( 'WPMS_SET_RETURN_PATH' ) ) {
+ $converted['mail']['return_path'] = WPMS_SET_RETURN_PATH;
+ }
+
+ /*
+ * SMTP settings.
+ */
+ if ( defined( 'WPMS_SMTP_HOST' ) ) {
+ $converted['smtp']['host'] = WPMS_SMTP_HOST;
+ }
+ if ( defined( 'WPMS_SMTP_PORT' ) ) {
+ $converted['smtp']['port'] = WPMS_SMTP_PORT;
+ }
+ if ( defined( 'WPMS_SSL' ) ) {
+ $converted['smtp']['ssl'] = WPMS_SSL;
+ }
+ if ( defined( 'WPMS_SMTP_AUTH' ) ) {
+ $converted['smtp']['auth'] = WPMS_SMTP_AUTH;
+ }
+ if ( defined( 'WPMS_SMTP_USER' ) ) {
+ $converted['smtp']['user'] = WPMS_SMTP_USER;
+ }
+ if ( defined( 'WPMS_SMTP_PASS' ) ) {
+ $converted['smtp']['pass'] = WPMS_SMTP_PASS;
+ }
+
+ return $converted;
+ }
+
+ /**
+ * Delete all old values that are stored separately each.
+ *
+ * @since 1.0.0
+ */
+ protected function clean_deprecated_data() {
+
+ foreach ( $this->old_keys as $old_key ) {
+ delete_option( $old_key );
+ }
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/src/MigrationAbstract.php b/wp-content/plugins/wp-mail-smtp/src/MigrationAbstract.php
new file mode 100755
index 00000000..088571f1
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/src/MigrationAbstract.php
@@ -0,0 +1,161 @@
+cur_ver = static::get_current_version();
+ }
+
+ /**
+ * Initialize migration.
+ *
+ * @since 3.0.0
+ */
+ public function init() {
+
+ $this->validate_db();
+ }
+
+ /**
+ * Whether migration is enabled.
+ *
+ * @since 3.0.0
+ *
+ * @return bool
+ */
+ public static function is_enabled() {
+
+ return true;
+ }
+
+ /**
+ * Static on purpose, to get current DB version without __construct() and validation.
+ *
+ * @since 3.0.0
+ *
+ * @return int
+ */
+ public static function get_current_version() {
+
+ return (int) get_option( static::OPTION_NAME, 0 );
+ }
+
+ /**
+ * Check DB version and update to the latest one.
+ *
+ * @since 3.0.0
+ */
+ protected function validate_db() {
+
+ if ( $this->cur_ver < static::DB_VERSION ) {
+ $this->run( static::DB_VERSION );
+ }
+ }
+
+ /**
+ * Update DB version in options table.
+ *
+ * @since 3.0.0
+ *
+ * @param int $version Version number.
+ */
+ protected function update_db_ver( $version = 0 ) {
+
+ $version = (int) $version;
+
+ if ( empty( $version ) ) {
+ $version = static::DB_VERSION;
+ }
+
+ // Autoload it, because this value is checked all the time
+ // and no need to request it separately from all autoloaded options.
+ update_option( static::OPTION_NAME, $version, true );
+ }
+
+ /**
+ * Prevent running the same migration twice.
+ * Run migration only when required.
+ *
+ * @since 3.0.0
+ *
+ * @param int $version The current migration version.
+ */
+ protected function maybe_required_older_migrations( $version ) {
+
+ $version = (int) $version;
+
+ if ( ( $version - $this->cur_ver ) > 1 ) {
+ $this->run( $version - 1 );
+ }
+ }
+
+ /**
+ * Actual migration launcher.
+ *
+ * @since 3.0.0
+ *
+ * @param int $version The specified migration version to run.
+ */
+ protected function run( $version ) {
+
+ $version = (int) $version;
+
+ if ( method_exists( $this, 'migrate_to_' . $version ) ) {
+ $this->{'migrate_to_' . $version}();
+ } else {
+ if ( WP::in_wp_admin() ) {
+ $message = sprintf( /* translators: %1$s - the DB option name, %2$s - WP Mail SMTP, %3$s - error message. */
+ esc_html__( 'There was an error while upgrading the %1$s database. Please contact %2$s support with this information: %3$s.', 'wp-mail-smtp' ),
+ static::OPTION_NAME,
+ 'WP Mail SMTP',
+ 'migration from v' . static::get_current_version() . ' to v' . static::DB_VERSION . ' failed. Plugin version: v' . WPMS_PLUGIN_VER . ''
+ );
+
+ WP::add_admin_notice( $message, WP::ADMIN_NOTICE_ERROR );
+ }
+ }
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/src/Migrations.php b/wp-content/plugins/wp-mail-smtp/src/Migrations.php
new file mode 100755
index 00000000..f98fb5f0
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/src/Migrations.php
@@ -0,0 +1,170 @@
+init_migrations();
+ }
+
+ /**
+ * Initialize DB migrations.
+ *
+ * @since 4.0.0
+ */
+ private function init_migrations() {
+
+ $migrations = $this->get_migrations();
+
+ foreach ( $migrations as $migration ) {
+ if ( is_subclass_of( $migration, MigrationAbstract::class ) && $migration::is_enabled() ) {
+ ( new $migration() )->init();
+ }
+ }
+ }
+
+ /**
+ * Get migrations classes.
+ *
+ * @since 4.0.0
+ *
+ * @return array Migrations classes.
+ */
+ private function get_migrations() {
+
+ $migrations = [
+ Migration::class,
+ DebugEventsMigration::class,
+ QueueMigration::class,
+ ];
+
+ /**
+ * Filters DB migrations classes.
+ *
+ * @deprecated 4.0.0
+ *
+ * @since 3.0.0
+ *
+ * @param array $migrations Migrations classes.
+ */
+ $migrations = apply_filters_deprecated(
+ 'wp_mail_smtp_core_init_migrations',
+ [ $migrations ],
+ '3.10.0',
+ 'wp_mail_smtp_migrations_get_migrations'
+ );
+
+ /**
+ * Filters DB migrations classes.
+ *
+ * @since 4.0.0
+ *
+ * @param array $migrations Migrations classes.
+ */
+ return apply_filters( 'wp_mail_smtp_migrations_get_migrations', $migrations );
+ }
+
+ /**
+ * Initialize DB migrations after plugin update.
+ * Initiate ajax call to perform the migration with the new plugin version code.
+ *
+ * @since 4.0.0
+ *
+ * @param WP_Upgrader $upgrader WP_Upgrader instance.
+ * @param array $options Array of update data.
+ */
+ public function init_migrations_after_upgrade( $upgrader, $options ) {
+
+ if (
+ // Skip if in admin panel.
+ ( is_admin() && ! wp_doing_ajax() ) ||
+ // Skip if it's update from plugins list page.
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+ ( wp_doing_ajax() && isset( $_REQUEST['action'] ) && $_REQUEST['action'] === 'update-plugin' )
+ ) {
+ return;
+ }
+
+ $plugins = [];
+
+ if ( isset( $options['plugins'] ) && is_array( $options['plugins'] ) ) {
+ $plugins = $options['plugins'];
+ } elseif ( isset( $options['plugin'] ) && is_string( $options['plugin'] ) ) {
+ $plugins = [ $options['plugin'] ];
+ }
+
+ if (
+ ! in_array( 'wp-mail-smtp/wp_mail_smtp.php', $plugins, true ) &&
+ ! in_array( 'wp-mail-smtp-pro/wp_mail_smtp.php', $plugins, true )
+ ) {
+ return;
+ }
+
+ $url = add_query_arg(
+ [
+ 'action' => 'wp_mail_smtp_init_migrations',
+ ],
+ admin_url( 'admin-ajax.php' )
+ );
+
+ $timeout = (int) ini_get( 'max_execution_time' );
+
+ $args = [
+ 'sslverify' => false,
+ 'timeout' => $timeout ? $timeout : 30,
+ ];
+
+ wp_remote_post( $url, $args );
+ }
+
+ /**
+ * Initialize migrations via AJAX request.
+ *
+ * @since 4.0.0
+ */
+ public function init_migrations_ajax_handler() {
+
+ $this->init_migrations();
+
+ wp_send_json_success();
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/src/OptimizedEmailSending.php b/wp-content/plugins/wp-mail-smtp/src/OptimizedEmailSending.php
new file mode 100755
index 00000000..2b68e1ba
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/src/OptimizedEmailSending.php
@@ -0,0 +1,59 @@
+get( 'general', self::SETTINGS_SLUG );
+
+ return (bool) $value;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/src/Options.php b/wp-content/plugins/wp-mail-smtp/src/Options.php
new file mode 100755
index 00000000..ee8866da
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/src/Options.php
@@ -0,0 +1,1815 @@
+ [
+ 'from_name',
+ 'from_email',
+ 'mailer',
+ 'return_path',
+ 'from_name_force',
+ 'from_email_force',
+ ],
+ 'smtp' => [
+ 'host',
+ 'port',
+ 'encryption',
+ 'autotls',
+ 'auth',
+ 'user',
+ 'pass',
+ ],
+ 'gmail' => [
+ 'one_click_setup_enabled',
+ 'client_id',
+ 'client_secret',
+ ],
+ 'outlook' => [
+ 'one_click_setup_enabled',
+ 'client_id',
+ 'client_secret',
+ ],
+ 'zoho' => [
+ 'domain',
+ 'client_id',
+ 'client_secret',
+ ],
+ 'amazonses' => [
+ 'client_id',
+ 'client_secret',
+ 'region',
+ ],
+ 'mailgun' => [
+ 'api_key',
+ 'domain',
+ 'region',
+ ],
+ 'mailjet' => [
+ 'api_key',
+ 'secret_key',
+ ],
+ 'mailersend' => [
+ 'api_key',
+ 'has_pro_plan',
+ ],
+ 'mandrill' => [
+ 'api_key',
+ ],
+ 'sendgrid' => [
+ 'api_key',
+ 'domain',
+ ],
+ 'sparkpost' => [
+ 'api_key',
+ 'region',
+ ],
+ 'postmark' => [
+ 'server_api_token',
+ 'message_stream',
+ ],
+ 'smtpcom' => [
+ 'api_key',
+ 'channel',
+ ],
+ 'sendinblue' => [
+ 'api_key',
+ 'domain',
+ ],
+ 'sendlayer' => [
+ 'api_key',
+ ],
+ 'elasticemail' => [
+ 'api_key',
+ ],
+ 'smtp2go' => [
+ 'api_key',
+ ],
+ 'resend' => [
+ 'api_key',
+ ],
+ 'pepipostapi' => [
+ 'api_key',
+ ],
+ 'pepipost' => [
+ 'host',
+ 'port',
+ 'encryption',
+ 'auth',
+ 'user',
+ 'pass',
+ ],
+ 'license' => [
+ 'key',
+ ],
+ 'alert_email' => [
+ 'enabled',
+ 'connections',
+ ],
+ 'alert_slack_webhook' => [
+ 'enabled',
+ 'connections',
+ ],
+ 'alert_discord_webhook' => [
+ 'enabled',
+ 'connections',
+ ],
+ 'alert_twilio_sms' => [
+ 'enabled',
+ 'connections',
+ ],
+ 'alert_custom_webhook' => [
+ 'enabled',
+ 'connections',
+ ],
+ 'alert_push_notifications' => [
+ 'enabled',
+ 'connections',
+ ],
+ 'alert_whatsapp' => [
+ 'enabled',
+ 'connections',
+ ],
+ 'alert_events' => [
+ 'email_hard_bounced',
+ ],
+ ];
+
+ /**
+ * List of all mailers (except PHP default mailer 'mail').
+ *
+ * @since 3.3.0
+ *
+ * @var string[]
+ */
+ public static $mailers = [
+ 'sendlayer',
+ 'smtpcom',
+ 'sendinblue',
+ 'amazonses',
+ 'gmail',
+ 'mailgun',
+ 'mailjet',
+ 'mailersend',
+ 'mandrill',
+ 'outlook',
+ 'postmark',
+ 'resend',
+ 'sendgrid',
+ 'sparkpost',
+ 'zoho',
+ 'elasticemail',
+ 'smtp2go',
+ 'smtp',
+ 'pepipost',
+ 'pepipostapi',
+ ];
+
+ /**
+ * That's where plugin options are saved in wp_options table.
+ *
+ * @since 1.0.0
+ *
+ * @var string
+ */
+ const META_KEY = 'wp_mail_smtp';
+
+ /**
+ * All instances of Options class that should be notified about options update.
+ *
+ * @since 3.7.0
+ *
+ * @var Options[]
+ */
+ protected static $update_observers;
+
+ /**
+ * Options data.
+ *
+ * @since 3.7.0
+ *
+ * @var array
+ */
+ protected $options = [];
+
+ /**
+ * Init the Options class.
+ * TODO: add a flag to process without retrieving const values.
+ *
+ * @since 1.0.0
+ * @since 3.3.0 Deprecated instantiation via new keyword. `Options::init()` must be used.
+ */
+ public function __construct() {
+
+ // Store all class instances that will be notified about options update.
+ static::$update_observers[] = $this;
+
+ $this->populate_options();
+ }
+
+ /**
+ * Initialize all the options.
+ *
+ * @since 1.0.0
+ *
+ * @return Options
+ */
+ public static function init() {
+
+ static $instance;
+
+ if ( ! $instance ) {
+ $instance = new self();
+ }
+
+ return $instance;
+ }
+
+ /**
+ * Whether current class is a main options.
+ *
+ * @since 3.7.0
+ *
+ * @var bool
+ */
+ protected function is_main_options() {
+
+ return true;
+ }
+
+ /**
+ * Default options that are saved on plugin activation.
+ *
+ * @since 1.3.0
+ * @since 2.1.0 Set the Force from email to "on" by default.
+ *
+ * @return array
+ */
+ public static function get_defaults() {
+
+ $defaults = [
+ 'mail' => [
+ 'from_email' => get_option( 'admin_email' ),
+ 'from_name' => get_bloginfo( 'name' ),
+ 'mailer' => 'mail',
+ 'return_path' => true,
+ 'from_email_force' => true,
+ 'from_name_force' => false,
+ ],
+ 'smtp' => [
+ 'autotls' => true,
+ 'auth' => true,
+ ],
+ 'general' => [
+ SummaryReportEmail::SETTINGS_SLUG => ! is_multisite() ? false : true,
+ ],
+ ];
+
+ /**
+ * Filters the default options.
+ *
+ * @since 3.11.0
+ *
+ * @param array $defaults Default options.
+ */
+ return apply_filters( 'wp_mail_smtp_options_get_defaults', $defaults );
+ }
+
+ /**
+ * Retrieve all options of the plugin.
+ *
+ * @since 1.0.0
+ * @since 2.2.0 Added the filter.
+ */
+ protected function populate_options() {
+
+ $this->options = apply_filters( 'wp_mail_smtp_populate_options', get_option( static::META_KEY, [] ) );
+ }
+
+ /**
+ * Get all the options.
+ *
+ * Options::init()->get_all();
+ *
+ * @since 1.0.0
+ *
+ * @return array
+ */
+ public function get_all() {
+
+ $options = $this->options;
+
+ foreach ( $options as $group => $g_value ) {
+ foreach ( $g_value as $key => $value ) {
+ $options[ $group ][ $key ] = $this->get( $group, $key );
+ }
+ }
+
+ return $this->is_main_options() ? apply_filters( 'wp_mail_smtp_options_get_all', $options ) : $options;
+ }
+
+ /**
+ * Get all the options for a group.
+ *
+ * Options::init()->get_group('smtp') - will return the array of options for the group, including defaults and constants.
+ *
+ * @since 1.0.0
+ * @since 1.5.0 Process values through the get() method which is aware of constants.
+ *
+ * @param string $group
+ *
+ * @return array
+ */
+ public function get_group( $group ) {
+
+ // Just to feel safe.
+ $group = sanitize_key( $group );
+
+ /*
+ * Get the values saved in DB.
+ * If plugin is configured with constants right from the start - this will not have all the values.
+ */
+ $options = isset( $this->options[ $group ] ) ? $this->options[ $group ] : [];
+
+ // We need to process certain constants-aware options through actual constants.
+ if ( isset( self::$map[ $group ] ) ) {
+ foreach ( self::$map[ $group ] as $key ) {
+ $options[ $key ] = $this->get( $group, $key );
+ }
+ }
+
+ return $this->is_main_options() ? apply_filters( 'wp_mail_smtp_options_get_group', $options, $group ) : $options;
+ }
+
+ /**
+ * Get options by a group and a key.
+ *
+ * Options::init()->get( 'smtp', 'host' ) - will return only SMTP 'host' option.
+ *
+ * @since 1.0.0
+ * @since 2.5.0 Added $strip_slashes method parameter.
+ *
+ * @param string $group The option group.
+ * @param string $key The option key.
+ * @param bool $strip_slashes If the slashes should be stripped from string values.
+ *
+ * @return mixed|null Null if value doesn't exist anywhere: in constants, in DB, in a map. So it's completely custom or a typo.
+ */
+ public function get( $group, $key, $strip_slashes = true ) {
+
+ // Just to feel safe.
+ $group = sanitize_key( $group );
+ $key = sanitize_key( $key );
+ $value = null;
+
+ // Get the const value if we have one.
+ $value = $this->get_const_value( $group, $key, $value );
+
+ // We don't have a const value.
+ if ( $value === null ) {
+ // Ordinary database or default values.
+ if ( isset( $this->options[ $group ] ) ) {
+ // Get the options key of a group.
+ if ( isset( $this->options[ $group ][ $key ] ) ) {
+ $value = $this->get_existing_option_value( $group, $key );
+ } else {
+ $value = $this->postprocess_key_defaults( $group, $key );
+ }
+ } else {
+ /*
+ * Fallback to default if it doesn't exist in a map.
+ * Allow to retrieve only values from a map.
+ */
+ if (
+ isset( self::$map[ $group ] ) &&
+ in_array( $key, self::$map[ $group ], true )
+ ) {
+ $value = $this->postprocess_key_defaults( $group, $key );
+ }
+ }
+ }
+
+ // Conditionally strip slashes only from values saved in DB. Constants should be processed as is.
+ if ( $strip_slashes && is_string( $value ) && ! $this->is_const_defined( $group, $key ) ) {
+ $value = stripslashes( $value );
+ }
+
+ return $this->is_main_options() ? apply_filters( 'wp_mail_smtp_options_get', $value, $group, $key ) : $value;
+ }
+
+ /**
+ * Get the existing cached option value.
+ *
+ * @since 2.5.0
+ *
+ * @param string $group The options group.
+ * @param string $key The options key.
+ *
+ * @return mixed
+ */
+ private function get_existing_option_value( $group, $key ) {
+
+ if ( $group === 'smtp' && $key === 'pass' ) {
+ try {
+ return Crypto::decrypt( $this->options[ $group ][ $key ] );
+ } catch ( \Exception $e ) {
+ return $this->options[ $group ][ $key ];
+ }
+ }
+
+ return $this->options[ $group ][ $key ];
+ }
+
+ /**
+ * Some options may be non-empty by default,
+ * so we need to postprocess them to convert.
+ *
+ * @since 1.0.0
+ * @since 1.4.0 Added Mailgun:region.
+ * @since 1.5.0 Added Outlook/AmazonSES, license key support.
+ *
+ * @param string $group
+ * @param string $key
+ *
+ * @return mixed
+ */
+ protected function postprocess_key_defaults( $group, $key ) {
+
+ $value = '';
+
+ switch ( $key ) {
+ case 'from_email_force':
+ case 'from_name_force':
+ case 'return_path':
+ $value = $group === 'mail' ? false : true;
+ break;
+
+ case 'mailer':
+ $value = 'mail';
+ break;
+
+ case 'encryption':
+ $value = in_array( $group, [ 'smtp', 'pepipost' ], true ) ? 'none' : $value;
+ break;
+
+ case 'region':
+ $value = $group === 'mailgun' || $group === 'sparkpost' ? 'US' : $value;
+ break;
+
+ case 'auth':
+ case 'autotls':
+ $value = in_array( $group, [ 'smtp', 'pepipost' ], true ) ? false : true;
+ break;
+
+ case 'pass':
+ $value = $this->get_const_value( $group, $key, $value );
+ break;
+
+ case 'type':
+ $value = $group === 'license' ? 'lite' : '';
+ break;
+ }
+
+ return apply_filters( 'wp_mail_smtp_options_postprocess_key_defaults', $value, $group, $key );
+ }
+
+ /**
+ * Process the options values through the constants check.
+ * If we have defined associated constant - use it instead of a DB value.
+ * Backward compatibility is hard.
+ * General section of options won't have constants, so we are omitting those checks and just return default value.
+ *
+ * @since 1.0.0
+ * @since 1.4.0 Added WPMS_MAILGUN_REGION.
+ * @since 1.5.0 Added Outlook/AmazonSES, license key support.
+ * @since 1.6.0 Added Sendinblue.
+ * @since 1.7.0 Added Do Not Send.
+ * @since 1.8.0 Added Pepipost API.
+ * @since 3.6.0 Added Debug Events Retention Period.
+ *
+ * @param string $group
+ * @param string $key
+ * @param mixed $value
+ *
+ * @return mixed
+ */
+ protected function get_const_value( $group, $key, $value ) {
+
+ if ( ! $this->is_const_enabled() ) {
+ return $value;
+ }
+
+ $return = null;
+
+ // phpcs:disable WPForms.Formatting.Switch.AddEmptyLineBefore, WPForms.Formatting.Switch.RemoveEmptyLineBefore
+ switch ( $group ) {
+ case 'mail':
+ switch ( $key ) {
+ case 'from_name':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? WPMS_MAIL_FROM_NAME : $value;
+ break;
+ case 'from_email':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? WPMS_MAIL_FROM : $value;
+ break;
+ case 'mailer':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? WPMS_MAILER : $value;
+ break;
+ case 'return_path':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? WPMS_SET_RETURN_PATH : $value;
+ break;
+ case 'from_name_force':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? WPMS_MAIL_FROM_NAME_FORCE : $value;
+ break;
+ case 'from_email_force':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? WPMS_MAIL_FROM_FORCE : $value;
+ break;
+ }
+
+ break;
+
+ case 'smtp':
+ switch ( $key ) {
+ case 'host':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? WPMS_SMTP_HOST : $value;
+ break;
+ case 'port':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? WPMS_SMTP_PORT : $value;
+ break;
+ case 'encryption':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? ( WPMS_SSL === '' ? 'none' : WPMS_SSL ) : $value;
+ break;
+ case 'auth':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? (bool) WPMS_SMTP_AUTH : $value;
+ break;
+ case 'autotls':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? (bool) WPMS_SMTP_AUTOTLS : $value;
+ break;
+ case 'user':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? WPMS_SMTP_USER : $value;
+ break;
+ case 'pass':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? WPMS_SMTP_PASS : $value;
+ break;
+ }
+
+ break;
+
+ case 'sendlayer':
+ switch ( $key ) {
+ case 'api_key':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? WPMS_SENDLAYER_API_KEY : $value;
+ break;
+ }
+
+ break;
+
+ case 'gmail':
+ switch ( $key ) {
+ case 'client_id':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? WPMS_GMAIL_CLIENT_ID : $value;
+ break;
+ case 'client_secret':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? WPMS_GMAIL_CLIENT_SECRET : $value;
+ break;
+ }
+
+ break;
+
+ case 'outlook':
+ switch ( $key ) {
+ case 'client_id':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? WPMS_OUTLOOK_CLIENT_ID : $value;
+ break;
+ case 'client_secret':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? WPMS_OUTLOOK_CLIENT_SECRET : $value;
+ break;
+ }
+
+ break;
+
+ case 'zoho':
+ switch ( $key ) {
+ case 'domain':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? WPMS_ZOHO_DOMAIN : $value;
+ break;
+ case 'client_id':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? WPMS_ZOHO_CLIENT_ID : $value;
+ break;
+ case 'client_secret':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? WPMS_ZOHO_CLIENT_SECRET : $value;
+ break;
+ }
+
+ break;
+
+ case 'amazonses':
+ switch ( $key ) {
+ case 'client_id':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? WPMS_AMAZONSES_CLIENT_ID : $value;
+ break;
+ case 'client_secret':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? WPMS_AMAZONSES_CLIENT_SECRET : $value;
+ break;
+ case 'region':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? WPMS_AMAZONSES_REGION : $value;
+ break;
+ }
+
+ break;
+
+ case 'mailgun':
+ switch ( $key ) {
+ case 'api_key':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? WPMS_MAILGUN_API_KEY : $value;
+ break;
+ case 'domain':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? WPMS_MAILGUN_DOMAIN : $value;
+ break;
+ case 'region':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? WPMS_MAILGUN_REGION : $value;
+ break;
+ }
+
+ break;
+
+ case 'mailjet':
+ switch ( $key ) {
+ case 'api_key':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? WPMS_MAILJET_API_KEY : $value;
+ break;
+ case 'secret_key':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? WPMS_MAILJET_SECRET_KEY : $value;
+ break;
+ }
+
+ break;
+
+ case 'sendgrid':
+ switch ( $key ) {
+ case 'api_key':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? WPMS_SENDGRID_API_KEY : $value;
+ break;
+ case 'domain':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? WPMS_SENDGRID_DOMAIN : $value;
+ break;
+ }
+
+ break;
+
+ case 'sparkpost':
+ switch ( $key ) {
+ case 'api_key':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? WPMS_SPARKPOST_API_KEY : $value;
+ break;
+ case 'region':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? WPMS_SPARKPOST_REGION : $value;
+ break;
+ }
+
+ break;
+
+ case 'postmark':
+ switch ( $key ) {
+ case 'server_api_token':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? WPMS_POSTMARK_SERVER_API_TOKEN : $value;
+ break;
+ case 'message_stream':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? WPMS_POSTMARK_MESSAGE_STREAM : $value;
+ break;
+ }
+
+ break;
+
+ case 'smtpcom':
+ switch ( $key ) {
+ case 'api_key':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? WPMS_SMTPCOM_API_KEY : $value;
+ break;
+ case 'channel':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? WPMS_SMTPCOM_CHANNEL : $value;
+ break;
+ }
+
+ break;
+
+ case 'sendinblue':
+ switch ( $key ) {
+ case 'api_key':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? WPMS_SENDINBLUE_API_KEY : $value;
+ break;
+ case 'domain':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? WPMS_SENDINBLUE_DOMAIN : $value;
+ break;
+ }
+
+ break;
+
+ case 'elasticemail':
+ switch ( $key ) {
+ case 'api_key':
+ $return = $this->is_const_defined( $group, $key ) ? WPMS_ELASTICEMAIL_API_KEY : $value;
+ break;
+ }
+
+ break;
+
+ case 'smtp2go':
+ switch ( $key ) {
+ case 'api_key':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? WPMS_SMTP2GO_API_KEY : $value;
+ break;
+ }
+
+ break;
+
+ case 'resend':
+ switch ( $key ) {
+ case 'api_key':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? WPMS_RESEND_API_KEY : $value;
+ break;
+ }
+
+ break;
+
+ case 'pepipostapi':
+ switch ( $key ) {
+ case 'api_key':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? WPMS_PEPIPOST_API_KEY : $value;
+ break;
+ }
+
+ break;
+
+ case 'alert_email':
+ switch ( $key ) {
+ case 'connections':
+ $return = $this->is_const_defined( $group, $key ) ? [ [ 'send_to' => WPMS_ALERT_EMAIL_SEND_TO ] ] : $value;
+ break;
+ }
+
+ break;
+
+ case 'alert_slack_webhook':
+ switch ( $key ) {
+ case 'connections':
+ $return = $this->is_const_defined( $group, $key ) ? [ [ 'webhook_url' => WPMS_ALERT_SLACK_WEBHOOK_URL ] ] : $value;
+ break;
+ }
+
+ break;
+
+ case 'alert_discord_webhook':
+ switch ( $key ) {
+ case 'connections':
+ $return = $this->is_const_defined( $group, $key ) ? [ [ 'webhook_url' => WPMS_ALERT_DISCORD_WEBHOOK_URL ] ] : $value;
+ break;
+ }
+
+ break;
+
+ case 'alert_teams_webhook':
+ switch ( $key ) {
+ case 'connections':
+ $return = $this->is_const_defined( $group, $key ) ? [ [ 'webhook_url' => WPMS_ALERT_TEAMS_WEBHOOK_URL ] ] : $value;
+ break;
+ }
+
+ break;
+
+ case 'alert_twilio_sms':
+ switch ( $key ) {
+ case 'connections':
+ if ( $this->is_const_defined( $group, $key ) ) {
+ $return = [
+ [
+ 'account_sid' => WPMS_ALERT_TWILIO_SMS_ACCOUNT_SID,
+ 'auth_token' => WPMS_ALERT_TWILIO_SMS_AUTH_TOKEN,
+ 'from_phone_number' => WPMS_ALERT_TWILIO_SMS_FROM_PHONE_NUMBER,
+ 'to_phone_number' => WPMS_ALERT_TWILIO_SMS_TO_PHONE_NUMBER,
+ ],
+ ];
+ } else {
+ $return = $value;
+ }
+ break;
+ }
+
+ break;
+
+ case 'alert_custom_webhook':
+ switch ( $key ) {
+ case 'connections':
+ $return = $this->is_const_defined( $group, $key ) ? [ [ 'webhook_url' => WPMS_ALERT_CUSTOM_WEBHOOK_URL ] ] : $value;
+ break;
+ }
+
+ break;
+
+ case 'license':
+ switch ( $key ) {
+ case 'key':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? WPMS_LICENSE_KEY : $value;
+ break;
+ }
+
+ break;
+
+ case 'general':
+ switch ( $key ) {
+ case 'do_not_send':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? WPMS_DO_NOT_SEND : $value;
+ break;
+
+ case SummaryReportEmail::SETTINGS_SLUG:
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ?
+ $this->parse_boolean( WPMS_SUMMARY_REPORT_EMAIL_DISABLED ) :
+ $value;
+ break;
+
+ case OptimizedEmailSending::SETTINGS_SLUG:
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ?
+ $this->parse_boolean( WPMS_OPTIMIZED_EMAIL_SENDING_ENABLED ) :
+ $value;
+ break;
+ }
+
+ break;
+
+ case 'debug_events':
+ switch ( $key ) {
+ case 'retention_period':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? intval( WPMS_DEBUG_EVENTS_RETENTION_PERIOD ) : $value;
+ break;
+ }
+
+ break;
+
+ case 'mailersend':
+ switch ( $key ) {
+ case 'api_key':
+ $return = $this->is_const_defined( $group, $key ) ? WPMS_MAILERSEND_API_KEY : $value;
+ break;
+
+ case 'has_pro_plan':
+ $return = $this->is_const_defined( $group, $key ) ? $this->parse_boolean( WPMS_MAILERSEND_HAS_PRO_PLAN ) : $value;
+ break;
+ }
+ break;
+
+ case 'mandrill':
+ if ( $key === 'api_key' ) {
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = $this->is_const_defined( $group, $key ) ? WPMS_MANDRILL_API_KEY : $value;
+ }
+
+ break;
+
+ case 'alert_whatsapp':
+ switch ( $key ) {
+ case 'connections':
+ if ( $this->is_const_defined( $group, $key ) ) {
+ $return = [
+ [
+ 'access_token' => WPMS_ALERT_WHATSAPP_ACCESS_TOKEN,
+ 'whatsapp_business_id' => WPMS_ALERT_WHATSAPP_BUSINESS_ID,
+ 'phone_number_id' => WPMS_ALERT_WHATSAPP_PHONE_NUMBER_ID,
+ 'to_phone_number' => WPMS_ALERT_WHATSAPP_TO_PHONE_NUMBER,
+ 'template_language' => WPMS_ALERT_WHATSAPP_TEMPLATE_LANGUAGE,
+ ],
+ ];
+ } else {
+ $return = $value;
+ }
+ break;
+ }
+
+ break;
+
+ default:
+ // Always return the default value if nothing from above matches the request.
+ $return = $value;
+ }
+
+ // phpcs:enable WPForms.Formatting.Switch.AddEmptyLineBefore, WPForms.Formatting.Switch.RemoveEmptyLineBefore
+
+ return apply_filters( 'wp_mail_smtp_options_get_const_value', $return, $group, $key, $value );
+ }
+
+ /**
+ * Whether constants redefinition is enabled or not.
+ *
+ * @since 1.0.0
+ * @since 1.5.0 Added filter to redefine the value.
+ *
+ * @return bool
+ */
+ public function is_const_enabled() {
+
+ $return = defined( 'WPMS_ON' ) && WPMS_ON === true;
+
+ return apply_filters( 'wp_mail_smtp_options_is_const_enabled', $return );
+ }
+
+ /**
+ * We need this check to reuse later in admin area,
+ * to distinguish settings fields that were redefined,
+ * and display them differently.
+ *
+ * @since 1.0.0
+ * @since 1.5.0 Added a filter, Outlook/AmazonSES, license key support.
+ * @since 1.6.0 Added Sendinblue.
+ * @since 1.7.0 Added Do Not Send.
+ * @since 1.8.0 Added Pepipost API.
+ *
+ * @param string $group
+ * @param string $key
+ *
+ * @return bool
+ */
+ public function is_const_defined( $group, $key ) {
+
+ if ( ! $this->is_const_enabled() ) {
+ return false;
+ }
+
+ // Just to feel safe.
+ $group = sanitize_key( $group );
+ $key = sanitize_key( $key );
+ $return = false;
+
+ // phpcs:disable WPForms.Formatting.Switch.AddEmptyLineBefore, WPForms.Formatting.Switch.RemoveEmptyLineBefore
+ switch ( $group ) {
+ case 'mail':
+ switch ( $key ) {
+ case 'from_name':
+ $return = defined( 'WPMS_MAIL_FROM_NAME' ) && WPMS_MAIL_FROM_NAME;
+ break;
+ case 'from_email':
+ $return = defined( 'WPMS_MAIL_FROM' ) && WPMS_MAIL_FROM;
+ break;
+ case 'mailer':
+ $return = defined( 'WPMS_MAILER' ) && WPMS_MAILER;
+ break;
+ case 'return_path':
+ $return = defined( 'WPMS_SET_RETURN_PATH' ) && ( WPMS_SET_RETURN_PATH === 'true' || WPMS_SET_RETURN_PATH === true );
+ break;
+ case 'from_name_force':
+ $return = defined( 'WPMS_MAIL_FROM_NAME_FORCE' ) && ( WPMS_MAIL_FROM_NAME_FORCE === 'true' || WPMS_MAIL_FROM_NAME_FORCE === true );
+ break;
+ case 'from_email_force':
+ $return = defined( 'WPMS_MAIL_FROM_FORCE' ) && ( WPMS_MAIL_FROM_FORCE === 'true' || WPMS_MAIL_FROM_FORCE === true );
+ break;
+ }
+
+ break;
+
+ case 'smtp':
+ switch ( $key ) {
+ case 'host':
+ $return = defined( 'WPMS_SMTP_HOST' ) && WPMS_SMTP_HOST;
+ break;
+ case 'port':
+ $return = defined( 'WPMS_SMTP_PORT' ) && WPMS_SMTP_PORT;
+ break;
+ case 'encryption':
+ $return = defined( 'WPMS_SSL' );
+ break;
+ case 'auth':
+ $return = defined( 'WPMS_SMTP_AUTH' );
+ break;
+ case 'autotls':
+ $return = defined( 'WPMS_SMTP_AUTOTLS' );
+ break;
+ case 'user':
+ $return = defined( 'WPMS_SMTP_USER' ) && WPMS_SMTP_USER;
+ break;
+ case 'pass':
+ $return = defined( 'WPMS_SMTP_PASS' ) && WPMS_SMTP_PASS;
+ break;
+ }
+
+ break;
+
+ case 'sendlayer':
+ switch ( $key ) {
+ case 'api_key':
+ $return = defined( 'WPMS_SENDLAYER_API_KEY' ) && WPMS_SENDLAYER_API_KEY;
+ break;
+ }
+
+ break;
+
+ case 'gmail':
+ switch ( $key ) {
+ case 'client_id':
+ $return = defined( 'WPMS_GMAIL_CLIENT_ID' ) && WPMS_GMAIL_CLIENT_ID;
+ break;
+ case 'client_secret':
+ $return = defined( 'WPMS_GMAIL_CLIENT_SECRET' ) && WPMS_GMAIL_CLIENT_SECRET;
+ break;
+ }
+
+ break;
+
+ case 'outlook':
+ switch ( $key ) {
+ case 'client_id':
+ $return = defined( 'WPMS_OUTLOOK_CLIENT_ID' ) && WPMS_OUTLOOK_CLIENT_ID;
+ break;
+ case 'client_secret':
+ $return = defined( 'WPMS_OUTLOOK_CLIENT_SECRET' ) && WPMS_OUTLOOK_CLIENT_SECRET;
+ break;
+ }
+
+ break;
+
+ case 'zoho':
+ switch ( $key ) {
+ case 'domain':
+ $return = defined( 'WPMS_ZOHO_DOMAIN' ) && WPMS_ZOHO_DOMAIN;
+ break;
+ case 'client_id':
+ $return = defined( 'WPMS_ZOHO_CLIENT_ID' ) && WPMS_ZOHO_CLIENT_ID;
+ break;
+ case 'client_secret':
+ $return = defined( 'WPMS_ZOHO_CLIENT_SECRET' ) && WPMS_ZOHO_CLIENT_SECRET;
+ break;
+ }
+
+ break;
+
+ case 'amazonses':
+ switch ( $key ) {
+ case 'client_id':
+ $return = defined( 'WPMS_AMAZONSES_CLIENT_ID' ) && WPMS_AMAZONSES_CLIENT_ID;
+ break;
+ case 'client_secret':
+ $return = defined( 'WPMS_AMAZONSES_CLIENT_SECRET' ) && WPMS_AMAZONSES_CLIENT_SECRET;
+ break;
+ case 'region':
+ $return = defined( 'WPMS_AMAZONSES_REGION' ) && WPMS_AMAZONSES_REGION;
+ break;
+ }
+
+ break;
+
+ case 'mailgun':
+ switch ( $key ) {
+ case 'api_key':
+ $return = defined( 'WPMS_MAILGUN_API_KEY' ) && WPMS_MAILGUN_API_KEY;
+ break;
+ case 'domain':
+ $return = defined( 'WPMS_MAILGUN_DOMAIN' ) && WPMS_MAILGUN_DOMAIN;
+ break;
+ case 'region':
+ $return = defined( 'WPMS_MAILGUN_REGION' ) && WPMS_MAILGUN_REGION;
+ break;
+ }
+
+ break;
+
+ case 'mailjet':
+ switch ( $key ) {
+ case 'api_key':
+ $return = defined( 'WPMS_MAILJET_API_KEY' ) && WPMS_MAILJET_API_KEY;
+ break;
+ case 'secret_key':
+ $return = defined( 'WPMS_MAILJET_SECRET_KEY' ) && WPMS_MAILJET_SECRET_KEY;
+ break;
+ }
+
+ break;
+
+ case 'sendgrid':
+ switch ( $key ) {
+ case 'api_key':
+ $return = defined( 'WPMS_SENDGRID_API_KEY' ) && WPMS_SENDGRID_API_KEY;
+ break;
+ case 'domain':
+ $return = defined( 'WPMS_SENDGRID_DOMAIN' ) && WPMS_SENDGRID_DOMAIN;
+ break;
+ }
+
+ break;
+
+ case 'sparkpost':
+ switch ( $key ) {
+ case 'api_key':
+ $return = defined( 'WPMS_SPARKPOST_API_KEY' ) && WPMS_SPARKPOST_API_KEY;
+ break;
+ case 'region':
+ $return = defined( 'WPMS_SPARKPOST_REGION' ) && WPMS_SPARKPOST_REGION;
+ break;
+ }
+
+ break;
+
+ case 'postmark':
+ switch ( $key ) {
+ case 'server_api_token':
+ $return = defined( 'WPMS_POSTMARK_SERVER_API_TOKEN' ) && WPMS_POSTMARK_SERVER_API_TOKEN;
+ break;
+ case 'message_stream':
+ $return = defined( 'WPMS_POSTMARK_MESSAGE_STREAM' ) && WPMS_POSTMARK_MESSAGE_STREAM;
+ break;
+ }
+
+ break;
+
+ case 'smtpcom':
+ switch ( $key ) {
+ case 'api_key':
+ $return = defined( 'WPMS_SMTPCOM_API_KEY' ) && WPMS_SMTPCOM_API_KEY;
+ break;
+ case 'channel':
+ $return = defined( 'WPMS_SMTPCOM_CHANNEL' ) && WPMS_SMTPCOM_CHANNEL;
+ break;
+ }
+
+ break;
+
+ case 'sendinblue':
+ switch ( $key ) {
+ case 'api_key':
+ $return = defined( 'WPMS_SENDINBLUE_API_KEY' ) && WPMS_SENDINBLUE_API_KEY;
+ break;
+ case 'domain':
+ $return = defined( 'WPMS_SENDINBLUE_DOMAIN' ) && WPMS_SENDINBLUE_DOMAIN;
+ break;
+ }
+
+ break;
+
+ case 'elasticemail':
+ switch ( $key ) {
+ case 'api_key':
+ $return = defined( 'WPMS_ELASTICEMAIL_API_KEY' ) && WPMS_ELASTICEMAIL_API_KEY;
+ break;
+ }
+
+ break;
+
+ case 'smtp2go':
+ switch ( $key ) {
+ case 'api_key':
+ $return = defined( 'WPMS_SMTP2GO_API_KEY' ) && WPMS_SMTP2GO_API_KEY;
+ break;
+ }
+
+ break;
+
+ case 'resend':
+ switch ( $key ) {
+ case 'api_key':
+ $return = defined( 'WPMS_RESEND_API_KEY' ) && WPMS_RESEND_API_KEY;
+ break;
+ }
+
+ break;
+
+ case 'pepipostapi':
+ switch ( $key ) {
+ case 'api_key':
+ $return = defined( 'WPMS_PEPIPOST_API_KEY' ) && WPMS_PEPIPOST_API_KEY;
+ break;
+ }
+
+ break;
+
+ case 'alert_email':
+ switch ( $key ) {
+ case 'connections':
+ $return = defined( 'WPMS_ALERT_EMAIL_SEND_TO' ) && WPMS_ALERT_EMAIL_SEND_TO;
+ break;
+ }
+
+ break;
+
+ case 'alert_slack_webhook':
+ switch ( $key ) {
+ case 'connections':
+ $return = defined( 'WPMS_ALERT_SLACK_WEBHOOK_URL' ) && WPMS_ALERT_SLACK_WEBHOOK_URL;
+ break;
+ }
+
+ break;
+
+ case 'alert_discord_webhook':
+ switch ( $key ) {
+ case 'connections':
+ $return = defined( 'WPMS_ALERT_DISCORD_WEBHOOK_URL' ) && WPMS_ALERT_DISCORD_WEBHOOK_URL;
+ break;
+ }
+
+ break;
+
+ case 'alert_teams_webhook':
+ switch ( $key ) {
+ case 'connections':
+ $return = defined( 'WPMS_ALERT_TEAMS_WEBHOOK_URL' ) && WPMS_ALERT_TEAMS_WEBHOOK_URL;
+ break;
+ }
+
+ break;
+
+ case 'alert_twilio_sms':
+ switch ( $key ) {
+ case 'connections':
+ $return = defined( 'WPMS_ALERT_TWILIO_SMS_ACCOUNT_SID' ) && WPMS_ALERT_TWILIO_SMS_ACCOUNT_SID &&
+ defined( 'WPMS_ALERT_TWILIO_SMS_AUTH_TOKEN' ) && WPMS_ALERT_TWILIO_SMS_AUTH_TOKEN &&
+ defined( 'WPMS_ALERT_TWILIO_SMS_FROM_PHONE_NUMBER' ) && WPMS_ALERT_TWILIO_SMS_FROM_PHONE_NUMBER &&
+ defined( 'WPMS_ALERT_TWILIO_SMS_TO_PHONE_NUMBER' ) && WPMS_ALERT_TWILIO_SMS_TO_PHONE_NUMBER;
+ break;
+ }
+
+ break;
+
+ case 'alert_custom_webhook':
+ switch ( $key ) {
+ case 'connections':
+ $return = defined( 'WPMS_ALERT_CUSTOM_WEBHOOK_URL' ) && WPMS_ALERT_CUSTOM_WEBHOOK_URL;
+ break;
+ }
+
+ break;
+
+ case 'alert_whatsapp':
+ switch ( $key ) {
+ case 'connections':
+ $return = defined( 'WPMS_ALERT_WHATSAPP_ACCESS_TOKEN' ) && WPMS_ALERT_WHATSAPP_ACCESS_TOKEN &&
+ defined( 'WPMS_ALERT_WHATSAPP_BUSINESS_ID' ) && WPMS_ALERT_WHATSAPP_BUSINESS_ID &&
+ defined( 'WPMS_ALERT_WHATSAPP_PHONE_NUMBER_ID' ) && WPMS_ALERT_WHATSAPP_PHONE_NUMBER_ID &&
+ defined( 'WPMS_ALERT_WHATSAPP_TO_PHONE_NUMBER' ) && WPMS_ALERT_WHATSAPP_TO_PHONE_NUMBER &&
+ defined( 'WPMS_ALERT_WHATSAPP_TEMPLATE_LANGUAGE' ) && WPMS_ALERT_WHATSAPP_TEMPLATE_LANGUAGE;
+ break;
+ }
+
+ break;
+
+ case 'license':
+ switch ( $key ) {
+ case 'key':
+ $return = defined( 'WPMS_LICENSE_KEY' ) && WPMS_LICENSE_KEY;
+ break;
+ }
+
+ break;
+
+ case 'general':
+ switch ( $key ) {
+ case 'do_not_send':
+ /** No inspection comment @noinspection PhpUndefinedConstantInspection */
+ $return = defined( 'WPMS_DO_NOT_SEND' ) && WPMS_DO_NOT_SEND;
+ break;
+
+ case SummaryReportEmail::SETTINGS_SLUG:
+ $return = defined( 'WPMS_SUMMARY_REPORT_EMAIL_DISABLED' );
+ break;
+
+ case OptimizedEmailSending::SETTINGS_SLUG:
+ $return = defined( 'WPMS_OPTIMIZED_EMAIL_SENDING_ENABLED' );
+ break;
+ }
+
+ break;
+
+ case 'debug_events':
+ switch ( $key ) {
+ case 'retention_period':
+ $return = defined( 'WPMS_DEBUG_EVENTS_RETENTION_PERIOD' );
+ break;
+ }
+
+ break;
+
+ case 'mailersend':
+ switch ( $key ) {
+ case 'api_key':
+ $return = defined( 'WPMS_MAILERSEND_API_KEY' ) && WPMS_MAILERSEND_API_KEY;
+ break;
+
+ case 'has_pro_plan':
+ $return = defined( 'WPMS_MAILERSEND_HAS_PRO_PLAN' );
+ break;
+ }
+ break;
+
+ case 'mandrill': // phpcs:ignore PSR2.ControlStructures.SwitchDeclaration.BodyOnNextLineCASE
+
+ switch ( $key ) {
+ case 'api_key':
+ $return = defined( 'WPMS_MANDRILL_API_KEY' ) && WPMS_MANDRILL_API_KEY;
+ break;
+ }
+
+ break;
+ }
+
+ // phpcs:enable WPForms.Formatting.Switch.AddEmptyLineBefore, WPForms.Formatting.Switch.RemoveEmptyLineBefore
+
+ return apply_filters( 'wp_mail_smtp_options_is_const_defined', $return, $group, $key );
+ }
+
+ /**
+ * Set plugin options, all at once.
+ *
+ * @since 1.0.0
+ * @since 1.3.0 Added $once argument to save options only if they don't exist already.
+ * @since 1.4.0 Added Mailgun:region.
+ * @since 1.5.0 Added Outlook/AmazonSES, Email Log. Stop saving const values into DB.
+ * @since 2.5.0 Added $overwrite_existing method parameter.
+ *
+ * @param array $options Plugin options to save.
+ * @param bool $once Whether to update existing options or to add these options only once.
+ * @param bool $overwrite_existing Whether to overwrite existing settings or merge these passed options with existing ones.
+ */
+ public function set( $options, $once = false, $overwrite_existing = true ) {
+
+ // Merge existing settings with new values.
+ if ( ! $overwrite_existing ) {
+ $options = self::array_merge_recursive( $this->get_all_raw(), $options );
+ }
+
+ $options = $this->process_generic_options( $options );
+ $options = $this->process_mailer_specific_options( $options );
+ $options = apply_filters( 'wp_mail_smtp_options_set', $options );
+
+ $this->save_options( $options, $once );
+
+ do_action( 'wp_mail_smtp_options_set_after', $options );
+ }
+
+ /**
+ * Save options to DB.
+ *
+ * @since 3.7.0
+ *
+ * @param array $options Options to save.
+ * @param bool $once Whether to update existing options or to add these options only once.
+ */
+ protected function save_options( $options, $once ) {
+
+ // Whether to update existing options or to add these options only once if they don't exist yet.
+ if ( $once ) {
+ add_option( static::META_KEY, $options, '', 'no' ); // Do not autoload these options.
+ } else {
+ if ( is_multisite() && WP::use_global_plugin_settings() ) {
+ update_blog_option( get_main_site_id(), static::META_KEY, $options );
+ } else {
+ update_option( static::META_KEY, $options, 'no' );
+ }
+ }
+
+ // Now we need to re-cache values of all instances.
+ foreach ( static::$update_observers as $observer ) {
+ $observer->populate_options();
+ }
+ }
+
+ /**
+ * Process the generic plugin options.
+ *
+ * @since 2.5.0
+ *
+ * @param array $options The options array.
+ *
+ * @return array
+ */
+ protected function process_generic_options( $options ) { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.MaxExceeded, Generic.Metrics.NestingLevel.MaxExceeded
+
+ foreach ( (array) $options as $group => $keys ) {
+ foreach ( $keys as $option_name => $option_value ) {
+ switch ( $group ) {
+ case 'mail':
+ switch ( $option_name ) {
+ case 'from_name':
+ $options[ $group ][ $option_name ] = sanitize_text_field( $option_value );
+ break;
+ case 'mailer':
+ $mailer = sanitize_text_field( $option_value );
+
+ $mailer = in_array( $mailer, self::$mailers, true ) ? $mailer : 'mail';
+
+ $options[ $group ][ $option_name ] = $mailer;
+ break;
+ case 'from_email':
+ if ( filter_var( $option_value, FILTER_VALIDATE_EMAIL ) ) {
+ $options[ $group ][ $option_name ] = sanitize_email( $option_value );
+ } else {
+ $options[ $group ][ $option_name ] = sanitize_email(
+ wp_mail_smtp()->get_processor()->get_default_email()
+ );
+ }
+ break;
+ case 'return_path':
+ case 'from_name_force':
+ case 'from_email_force':
+ $options[ $group ][ $option_name ] = (bool) $option_value;
+ break;
+ }
+ break;
+
+ case 'general':
+ switch ( $option_name ) {
+ case 'do_not_send':
+ case 'am_notifications_hidden':
+ case 'email_delivery_errors_hidden':
+ case 'dashboard_widget_hidden':
+ case 'uninstall':
+ case UsageTracking::SETTINGS_SLUG:
+ case SummaryReportEmail::SETTINGS_SLUG:
+ case OptimizedEmailSending::SETTINGS_SLUG:
+ $options[ $group ][ $option_name ] = (bool) $option_value;
+ break;
+ }
+
+ case 'debug_events':
+ switch ( $option_name ) {
+ case 'email_debug':
+ $options[ $group ][ $option_name ] = (bool) $option_value;
+ break;
+ case 'retention_period':
+ $options[ $group ][ $option_name ] = (int) $option_value;
+ break;
+ }
+ }
+ }
+ }
+
+ return $options;
+ }
+
+ /**
+ * Process mailers-specific plugin options.
+ *
+ * @since 2.5.0
+ *
+ * @param array $options The options array.
+ *
+ * @return array
+ */
+ protected function process_mailer_specific_options( $options ) { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.MaxExceeded, Generic.Metrics.NestingLevel.MaxExceeded
+
+ if (
+ ! empty( $options['mail']['mailer'] ) &&
+ isset( $options[ $options['mail']['mailer'] ] ) &&
+ in_array( $options['mail']['mailer'], self::$mailers, true )
+ ) {
+
+ $mailer = $options['mail']['mailer'];
+
+ foreach ( $options[ $mailer ] as $option_name => $option_value ) {
+ switch ( $option_name ) {
+ case 'host': // smtp.
+ case 'user': // smtp.
+ case 'encryption': // smtp.
+ case 'region': // mailgun/amazonses/sparkpost.
+ $options[ $mailer ][ $option_name ] = $this->is_const_defined( $mailer, $option_name ) ? '' : sanitize_text_field( $option_value );
+ break; // smtp.
+ case 'port':
+ $options[ $mailer ][ $option_name ] = $this->is_const_defined( $mailer, $option_name ) ? 25 : (int) $option_value;
+ break;
+ case 'auth': // smtp.
+ case 'autotls': // smtp.
+ $option_value = (bool) $option_value;
+
+ $options[ $mailer ][ $option_name ] = $this->is_const_defined( $mailer, $option_name ) ? false : $option_value;
+ break;
+
+ case 'pass': // smtp.
+ // Do not process as they may contain certain special characters, but allow to be overwritten using constants.
+ $option_value = trim( (string) $option_value );
+ $options[ $mailer ][ $option_name ] = $this->is_const_defined( $mailer, $option_name ) ? '' : $option_value;
+
+ if ( $mailer === 'smtp' && ! $this->is_const_defined( 'smtp', 'pass' ) ) {
+ try {
+ $options[ $mailer ][ $option_name ] = Crypto::encrypt( $option_value );
+ } catch ( \Exception $e ) {
+ } // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedCatch, Squiz.Commenting.EmptyCatchComment.Missing, Squiz.ControlStructures.ControlSignature.NewlineAfterOpenBrace
+ }
+ break;
+
+ case 'api_key': // mailgun/sendgrid/sendinblue/pepipostapi/smtpcom/sparkpost/sendlayer/smtp2go/mailjet/elasticemail/resend.
+ case 'secret_key': // mailjet.
+ case 'domain': // mailgun/zoho/sendgrid/sendinblue.
+ case 'client_id': // gmail/outlook/amazonses/zoho.
+ case 'client_secret': // gmail/outlook/amazonses/zoho.
+ case 'auth_code': // gmail/outlook.
+ case 'channel': // smtpcom.
+ case 'server_api_token': // postmark.
+ case 'message_stream': // postmark.
+ $options[ $mailer ][ $option_name ] = $this->is_const_defined( $mailer, $option_name ) ? '' : sanitize_text_field( $option_value );
+ break;
+
+ case 'has_pro_plan': // mailersend.
+ $options[ $mailer ][ $option_name ] = $this->is_const_defined( $mailer, $option_name ) ? false : (bool) $option_value;
+ break;
+
+ case 'access_token': // gmail/outlook/zoho, is an array.
+ case 'user_details': // outlook/zoho, is an array.
+ // These options don't support constants.
+ $options[ $mailer ][ $option_name ] = $option_value;
+ break;
+ }
+ }
+ }
+
+ return $options;
+ }
+
+ /**
+ * Merge recursively, including a proper substitution of values in sub-arrays when keys are the same.
+ * It's more like array_merge() and array_merge_recursive() combined.
+ *
+ * @since 1.0.0
+ *
+ * @return array
+ */
+ public static function array_merge_recursive() {
+
+ $arrays = func_get_args();
+
+ if ( count( $arrays ) < 2 ) {
+ return isset( $arrays[0] ) ? $arrays[0] : [];
+ }
+
+ $merged = [];
+
+ while ( $arrays ) {
+ $array = array_shift( $arrays );
+
+ if ( ! is_array( $array ) ) {
+ return [];
+ }
+
+ if ( empty( $array ) ) {
+ continue;
+ }
+
+ foreach ( $array as $key => $value ) {
+ if ( is_string( $key ) ) {
+ if (
+ is_array( $value ) &&
+ array_key_exists( $key, $merged ) &&
+ is_array( $merged[ $key ] )
+ ) {
+ $merged[ $key ] = call_user_func( __METHOD__, $merged[ $key ], $value );
+ } else {
+ $merged[ $key ] = $value;
+ }
+ } else {
+ $merged[] = $value;
+ }
+ }
+ }
+
+ return $merged;
+ }
+
+ /**
+ * Check whether the site is using Pepipost SMTP or not.
+ *
+ * @since 1.0.0
+ *
+ * @return bool
+ */
+ public function is_pepipost_active() {
+
+ _deprecated_function(
+ __METHOD__,
+ '2.4.0',
+ 'WPMailSMTP\Options::is_mailer_active()'
+ );
+
+ return apply_filters( 'wp_mail_smtp_options_is_pepipost_active', $this->is_mailer_active( 'pepipost' ) );
+ }
+
+ /**
+ * Check whether the site is using provided mailer or not.
+ *
+ * @since 2.3.0
+ *
+ * @param string $mailer The mailer slug.
+ *
+ * @return bool
+ */
+ public function is_mailer_active( $mailer ) {
+
+ $mailer = sanitize_key( $mailer );
+
+ return apply_filters(
+ "wp_mail_smtp_options_is_mailer_active_{$mailer}",
+ $this->get( 'mail', 'mailer' ) === $mailer
+ );
+ }
+
+ /**
+ * Check whether the site is using Pepipost/SMTP as a mailer or not.
+ *
+ * @since 1.1.0
+ *
+ * @return bool
+ */
+ public function is_mailer_smtp() {
+
+ return apply_filters( 'wp_mail_smtp_options_is_mailer_smtp', in_array( $this->get( 'mail', 'mailer' ), [ 'pepipost', 'smtp' ], true ) );
+ }
+
+ /**
+ * Get all the options, but without stripping the slashes.
+ *
+ * @since 2.5.0
+ *
+ * @return array
+ */
+ public function get_all_raw() {
+
+ $options = $this->options;
+
+ foreach ( $options as $group => $g_value ) {
+ foreach ( $g_value as $key => $value ) {
+ $options[ $group ][ $key ] = $this->get( $group, $key, false );
+ }
+ }
+
+ return $options;
+ }
+
+ /**
+ * Parse boolean value from string.
+ *
+ * @since 2.8.0
+ *
+ * @param string|boolean $value String or boolean value.
+ *
+ * @return boolean
+ */
+ public function parse_boolean( $value ) {
+
+ // Return early if it's boolean.
+ if ( is_bool( $value ) ) {
+ return $value;
+ }
+
+ $value = trim( $value );
+
+ return $value === 'true';
+ }
+
+ /**
+ * Get a message of a constant that was set inside wp-config.php file.
+ *
+ * @since 2.8.0
+ *
+ * @param string $constant Constant name.
+ *
+ * @return string
+ */
+ public function get_const_set_message( $constant ) {
+
+ return sprintf( /* translators: %1$s - constant that was used; %2$s - file where it was used. */
+ esc_html__( 'The value of this field was set using a constant %1$s most likely inside %2$s of your WordPress installation.', 'wp-mail-smtp' ),
+ '' . esc_html( $constant ) . '',
+ 'wp-config.php'
+ );
+ }
+
+ /**
+ * Whether option was changed.
+ * Can be used only before option save to DB.
+ *
+ * @since 3.0.0
+ *
+ * @param string $new_value Submitted value (e.g from $_POST).
+ * @param string $group Group key.
+ * @param string $key Option key.
+ *
+ * @return bool
+ */
+ public function is_option_changed( $new_value, $group, $key ) {
+
+ $old_value = $this->get( $group, $key );
+
+ return $old_value !== $new_value;
+ }
+
+ /**
+ * Whether constant was changed.
+ * Can be used only for insecure options.
+ *
+ * @since 3.0.0
+ *
+ * @param string $group Group key.
+ * @param string $key Option key.
+ *
+ * @return bool
+ */
+ public function is_const_changed( $group, $key ) {
+
+ if ( ! $this->is_const_defined( $group, $key ) ) {
+ return false;
+ }
+
+ // Prevent double options update on multiple function call for same option.
+ static $cache = [];
+
+ $cache_key = $group . '_' . $key;
+
+ if ( isset( $cache[ $cache_key ] ) ) {
+ return $cache[ $cache_key ];
+ }
+
+ $value = $this->get( $group, $key );
+
+ // Get old value from DB.
+ add_filter( 'wp_mail_smtp_options_is_const_enabled', '__return_false', PHP_INT_MAX );
+ $old_value = $this->get( $group, $key );
+ remove_filter( 'wp_mail_smtp_options_is_const_enabled', '__return_false', PHP_INT_MAX );
+
+ $changed = $value !== $old_value;
+
+ // Save new constant value to DB.
+ if ( $changed ) {
+ $old_opt = $this->get_all_raw();
+
+ $old_opt[ $group ][ $key ] = $value;
+ $this->set( $old_opt );
+ }
+
+ $cache[ $cache_key ] = $changed;
+
+ return $changed;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/src/Processor.php b/wp-content/plugins/wp-mail-smtp/src/Processor.php
new file mode 100755
index 00000000..2fb1ce39
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/src/Processor.php
@@ -0,0 +1,529 @@
+connections_manager = wp_mail_smtp()->get_connections_manager();
+ } else {
+ $this->connections_manager = $connections_manager;
+ }
+ }
+
+ /**
+ * Assign all hooks to proper places.
+ *
+ * @since 1.0.0
+ */
+ public function hooks() {
+
+ add_action( 'phpmailer_init', array( $this, 'phpmailer_init' ) );
+
+ // High priority number tries to ensure our plugin code executes last and respects previous hooks, if not forced.
+ add_filter( 'wp_mail_from', array( $this, 'filter_mail_from_email' ), PHP_INT_MAX );
+ add_filter( 'wp_mail_from_name', array( $this, 'filter_mail_from_name' ), PHP_INT_MAX );
+
+ add_action( 'wp_mail', [ $this, 'capture_early_wp_mail_filter_call' ], - PHP_INT_MAX );
+ add_action( 'wp_mail', [ $this, 'capture_late_wp_mail_filter_call' ], PHP_INT_MAX );
+ }
+
+ /**
+ * Redefine certain PHPMailer options with our custom ones.
+ *
+ * @since 1.0.0
+ *
+ * @param \PHPMailer $phpmailer It's passed by reference, so no need to return anything.
+ */
+ public function phpmailer_init( $phpmailer ) { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.MaxExceeded
+
+ $connection = $this->connections_manager->get_mail_connection();
+ $connection_options = $connection->get_options();
+ $mailer = $connection->get_mailer_slug();
+
+ // Check that mailer is not blank, and if mailer=smtp, host is not blank.
+ if (
+ ! $mailer ||
+ ( 'smtp' === $mailer && ! $connection_options->get( 'smtp', 'host' ) )
+ ) {
+ return;
+ }
+
+ // If the mailer is pepipost, make sure we have a username and password.
+ if (
+ 'pepipost' === $mailer &&
+ ( ! $connection_options->get( 'pepipost', 'user' ) && ! $connection_options->get( 'pepipost', 'pass' ) )
+ ) {
+ return;
+ }
+
+ // phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
+
+ // Set the mailer type as per config above, this overrides the already called isMail method.
+ // It's basically always 'smtp'.
+ $phpmailer->Mailer = $mailer;
+
+ // Set the Sender (return-path) if required.
+ if ( $connection_options->get( 'mail', 'return_path' ) ) {
+ $phpmailer->Sender = $phpmailer->From;
+ }
+
+ // Set the SMTPSecure value, if set to none, leave this blank. Possible values: 'ssl', 'tls', ''.
+ if ( 'none' === $connection_options->get( $mailer, 'encryption' ) ) {
+ $phpmailer->SMTPSecure = '';
+ } else {
+ $phpmailer->SMTPSecure = $connection_options->get( $mailer, 'encryption' );
+ }
+
+ // Check if user has disabled SMTPAutoTLS.
+ if ( $connection_options->get( $mailer, 'encryption' ) !== 'tls' && ! $connection_options->get( $mailer, 'autotls' ) ) {
+ $phpmailer->SMTPAutoTLS = false;
+ }
+
+ // Check if original WP from email can be set as the reply_to attribute.
+ if ( $this->allow_setting_original_from_email_to_reply_to( $phpmailer->getReplyToAddresses(), $mailer ) ) {
+ $phpmailer->addReplyTo( $this->wp_mail_from );
+ }
+
+ // If we're sending via SMTP, set the host.
+ if ( 'smtp' === $mailer ) {
+ // Set the other options.
+ $phpmailer->Host = $connection_options->get( $mailer, 'host' );
+ $phpmailer->Port = $connection_options->get( $mailer, 'port' );
+
+ // If we're using smtp auth, set the username & password.
+ if ( $connection_options->get( $mailer, 'auth' ) ) {
+ $phpmailer->SMTPAuth = true;
+ $phpmailer->Username = $connection_options->get( $mailer, 'user' );
+ $phpmailer->Password = $connection_options->get( $mailer, 'pass' );
+ }
+ } elseif ( 'pepipost' === $mailer ) {
+ // Set the Pepipost settings for BC.
+ $phpmailer->Mailer = 'smtp';
+ $phpmailer->Host = 'smtp.pepipost.com';
+ $phpmailer->Port = $connection_options->get( $mailer, 'port' );
+ $phpmailer->SMTPSecure = $connection_options->get( $mailer, 'encryption' ) === 'none' ? '' : $connection_options->get( $mailer, 'encryption' );
+ $phpmailer->SMTPAuth = true;
+ $phpmailer->Username = $connection_options->get( $mailer, 'user' );
+ $phpmailer->Password = $connection_options->get( $mailer, 'pass' );
+ }
+
+ $phpmailer->Timeout = 30;
+ // phpcs:enable
+
+ // Maybe set default reply-to header.
+ $this->set_default_reply_to( $phpmailer );
+
+ // You can add your own options here.
+ // See the phpmailer documentation for more info: https://github.com/PHPMailer/PHPMailer/tree/5.2-stable.
+ /* @noinspection PhpUnusedLocalVariableInspection It's passed by reference. */
+ $phpmailer = apply_filters( 'wp_mail_smtp_custom_options', $phpmailer );
+ }
+
+ /**
+ * Check if it's allowed to set the original WP from email to the reply_to field.
+ *
+ * @since 2.1.0
+ *
+ * @param array $reply_to Array of currently set reply to emails.
+ * @param string $mailer The slug of current mailer.
+ *
+ * @return bool
+ */
+ protected function allow_setting_original_from_email_to_reply_to( $reply_to, $mailer ) {
+
+ $connection = $this->connections_manager->get_mail_connection();
+ $connection_options = $connection->get_options();
+ $forced = $connection_options->get( 'mail', 'from_email_force' );
+ $from_email = $connection_options->get( 'mail', 'from_email' );
+
+ if ( ! empty( $reply_to ) || empty( $this->wp_mail_from ) ) {
+ return false;
+ }
+
+ if ( in_array( $mailer, [ 'zoho' ], true ) ) {
+ $sender = $connection_options->get( $mailer, 'user_details' );
+ $from_email = ! empty( $sender['email'] ) ? $sender['email'] : '';
+ $forced = true;
+ }
+
+ if (
+ $from_email === $this->wp_mail_from ||
+ ! $forced
+ ) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * This method will be called every time 'smtp' and 'mail' mailers will be used to send emails.
+ *
+ * @since 1.3.0
+ * @since 1.5.0 Added a do_action() to be able to hook into.
+ *
+ * @param bool $is_sent If the email was sent.
+ * @param array $to To email address.
+ * @param array $cc CC email addresses.
+ * @param array $bcc BCC email addresses.
+ * @param string $subject The email subject.
+ * @param string $body The email body.
+ * @param string $from The from email address.
+ */
+ public static function send_callback( $is_sent, $to, $cc, $bcc, $subject, $body, $from ) {
+
+ if ( ! $is_sent ) {
+ // Add mailer to the beginning and save to display later.
+ Debug::set(
+ 'Mailer: ' . esc_html( wp_mail_smtp()->get_providers()->get_options( wp_mail_smtp()->get_connections_manager()->get_mail_connection()->get_mailer_slug() )->get_title() ) . "\r\n" .
+ 'PHPMailer was able to connect to SMTP server but failed while trying to send an email.'
+ );
+ } else {
+ Debug::clear();
+ }
+
+ do_action( 'wp_mail_smtp_mailcatcher_smtp_send_after', $is_sent, $to, $cc, $bcc, $subject, $body, $from );
+ }
+
+ /**
+ * Validate the email address.
+ *
+ * @since 3.6.0
+ *
+ * @param string $email The email address.
+ *
+ * @return boolean True if email address is valid, false on failure.
+ */
+ public static function is_email_callback( $email ) {
+
+ return (bool) is_email( $email );
+ }
+
+ /**
+ * Modify the email address that is used for sending emails.
+ *
+ * @since 1.0.0
+ * @since 1.3.0 Forcing email rewrite if option is selected.
+ * @since 1.7.0 Default email may be empty, so pay attention to that as well.
+ *
+ * @param string $wp_email The email address passed by the filter.
+ *
+ * @return string
+ */
+ public function filter_mail_from_email( $wp_email ) {
+
+ // Save the original from address.
+ $this->filtered_from_email = filter_var( $wp_email, FILTER_VALIDATE_EMAIL );
+
+ $connection = $this->connections_manager->get_mail_connection();
+ $connection_options = $connection->get_options();
+ $forced = $connection_options->get( 'mail', 'from_email_force' );
+ $from_email = $connection_options->get( 'mail', 'from_email' );
+ $def_email = WP::get_default_email();
+
+ // Save the "original" set WP email from address for later use.
+ if ( $wp_email !== $def_email ) {
+ $this->wp_mail_from = filter_var( $wp_email, FILTER_VALIDATE_EMAIL );
+ }
+
+ // Return FROM EMAIL if forced in settings.
+ if ( $forced && ! empty( $from_email ) ) {
+ return $from_email;
+ }
+
+ // If the FROM EMAIL is not the default, return it unchanged.
+ if ( ! empty( $def_email ) && $wp_email !== $def_email ) {
+ return $wp_email;
+ }
+
+ return ! empty( $from_email ) ? $from_email : $wp_email;
+ }
+
+ /**
+ * Modify the sender name that is used for sending emails.
+ *
+ * @since 1.0.0
+ * @since 1.3.0 Forcing name rewrite if option is selected.
+ *
+ * @param string $name The from name passed through the filter.
+ *
+ * @return string
+ */
+ public function filter_mail_from_name( $name ) {
+
+ // Save the original from name.
+ $this->filtered_from_name = $name;
+
+ $connection = $this->connections_manager->get_mail_connection();
+ $connection_options = $connection->get_options();
+ $force = $connection_options->get( 'mail', 'from_name_force' );
+
+ // If the FROM NAME is not the default and not forced, return it unchanged.
+ if ( ! $force && $name !== $this->get_default_name() ) {
+ return $name;
+ }
+
+ $name = $connection_options->get( 'mail', 'from_name' );
+
+ return $name;
+ }
+
+ /**
+ * Get the default email address based on domain name.
+ *
+ * @since 1.0.0
+ * @since 1.7.0 May return an empty string.
+ *
+ * @return string Empty string when we aren't able to get the site domain (CLI, misconfigured server etc).
+ */
+ public function get_default_email() {
+
+ $server_name = Geo::get_site_domain();
+
+ if ( empty( $server_name ) ) {
+ return '';
+ }
+
+ // Get rid of www.
+ $sitename = strtolower( $server_name );
+ if ( substr( $sitename, 0, 4 ) === 'www.' ) {
+ $sitename = substr( $sitename, 4 );
+ }
+
+ return 'wordpress@' . $sitename;
+ }
+
+ /**
+ * Get the default email FROM NAME generated by WordPress.
+ *
+ * @since 1.3.0
+ *
+ * @return string
+ */
+ public function get_default_name() {
+ return 'WordPress';
+ }
+
+ /**
+ * Get or create the phpmailer.
+ *
+ * @since 1.9.0
+ *
+ * @return MailCatcherInterface
+ */
+ public function get_phpmailer() {
+
+ global $phpmailer;
+
+ // Make sure the PHPMailer class has been instantiated.
+ if ( ! is_object( $phpmailer ) || ! is_a( $phpmailer, 'PHPMailer' ) ) {
+ $phpmailer = wp_mail_smtp()->generate_mail_catcher( true ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
+ }
+
+ return $phpmailer;
+ }
+
+ /**
+ * Set the default reply_to header, if:
+ * - no other reply_to headers are already set and,
+ * - the default reply_to address filter `wp_mail_smtp_processor_default_reply_to_addresses` is configured.
+ *
+ * @since 2.1.1
+ *
+ * @param MailCatcherInterface $phpmailer The PHPMailer object.
+ */
+ private function set_default_reply_to( $phpmailer ) {
+
+ if ( ! empty( $phpmailer->getReplyToAddresses() ) ) {
+ return;
+ }
+
+ $default_reply_to_emails = apply_filters( 'wp_mail_smtp_processor_set_default_reply_to', '' );
+
+ if ( empty( $default_reply_to_emails ) ) {
+ return;
+ }
+
+ foreach ( explode( ',', $default_reply_to_emails ) as $email ) {
+ $email = trim( $email );
+
+ if ( filter_var( $email, FILTER_VALIDATE_EMAIL ) ) {
+ $phpmailer->addReplyTo( $email );
+ }
+ }
+ }
+
+ /**
+ * Capture `wp_mail` filter call on earliest priority.
+ *
+ * Currently used to capture the original `wp_mail` arguments before they are filtered.
+ *
+ * @since 4.0.0
+ *
+ * @param array $args The original `wp_mail` arguments.
+ *
+ * @return array
+ */
+ public function capture_early_wp_mail_filter_call( $args ) {
+
+ $this->original_wp_mail_args = $args;
+
+ return $args;
+ }
+
+ /**
+ * Capture `wp_mail` filter call on latest priority.
+ *
+ * Currently used to capture the `wp_mail` arguments after they are filtered
+ * and capture `wp_mail` function call.
+ *
+ * @since 4.0.0
+ *
+ * @param array $args The filtered `wp_mail` arguments.
+ *
+ * @return array
+ */
+ public function capture_late_wp_mail_filter_call( $args ) {
+
+ $this->filtered_wp_mail_args = $args;
+
+ $this->capture_wp_mail_call();
+
+ return $args;
+ }
+
+ /**
+ * Capture `wp_mail` function call.
+ *
+ * @since 4.0.0
+ */
+ private function capture_wp_mail_call() {
+
+ /**
+ * Fires on `wp_mail` function call.
+ *
+ * @since 4.0.0
+ */
+ do_action( 'wp_mail_smtp_processor_capture_wp_mail_call' );
+ }
+
+ /**
+ * Get the original `wp_mail` arguments.
+ *
+ * @since 4.0.0
+ *
+ * @return array
+ */
+ public function get_original_wp_mail_args() {
+
+ return $this->original_wp_mail_args;
+ }
+
+ /**
+ * Get the filtered `wp_mail` arguments.
+ *
+ * @since 4.0.0
+ *
+ * @return array
+ */
+ public function get_filtered_wp_mail_args() {
+
+ return $this->filtered_wp_mail_args;
+ }
+
+ /**
+ * Get the filtered `wp_mail_from` value.
+ *
+ * @since 4.0.0
+ *
+ * @return string
+ */
+ public function get_filtered_from_email() {
+
+ return $this->filtered_from_email;
+ }
+
+ /**
+ * Get the filtered `wp_mail_from_name` value.
+ *
+ * @since 4.0.0
+ *
+ * @return string
+ */
+ public function get_filtered_from_name() {
+
+ return $this->filtered_from_name;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/src/Providers/AmazonSES/Options.php b/wp-content/plugins/wp-mail-smtp/src/Providers/AmazonSES/Options.php
new file mode 100755
index 00000000..57d5c95e
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/src/Providers/AmazonSES/Options.php
@@ -0,0 +1,44 @@
+ wp_mail_smtp()->assets_url . '/images/providers/aws.svg',
+ 'slug' => 'amazonses',
+ 'title' => esc_html__( 'Amazon SES', 'wp-mail-smtp' ),
+ 'disabled' => true,
+ )
+ );
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function display_options() {
+
+ ?>
+
+
+
+
+
+ connection = $connection;
+ } else {
+ $this->connection = wp_mail_smtp()->get_connections_manager()->get_primary_connection();
+ }
+
+ $this->connection_options = $this->connection->get_options();
+ $this->mailer_slug = $this->connection->get_mailer_slug();
+ }
+
+ /**
+ * Use the composer autoloader to include the auth library and all dependencies.
+ *
+ * @since 1.0.0
+ */
+ protected function include_vendor_lib() {
+
+ require_once wp_mail_smtp()->plugin_path . '/vendor/autoload.php';
+ }
+
+ /**
+ * Get the url, that users will be redirected back to finish the OAuth process.
+ *
+ * @since 1.0.0
+ *
+ * @return string
+ */
+ public static function get_plugin_auth_url() {
+
+ return add_query_arg( 'tab', 'auth', wp_mail_smtp()->get_admin()->get_admin_page_url() );
+ }
+
+ /**
+ * Update auth code in our DB.
+ *
+ * @since 1.0.0
+ *
+ * @param string $code
+ */
+ protected function update_auth_code( $code ) {
+
+ $all = $this->connection_options->get_all();
+
+ // To save in DB.
+ $all[ $this->mailer_slug ]['auth_code'] = $code;
+
+ // To save in currently retrieved options array.
+ $this->options['auth_code'] = $code;
+
+ // NOTE: These options need to be saved by overwriting all options, because WP automatic updates can cause an issue: GH #575!
+ $this->connection_options->set( $all, false, true );
+ }
+
+ /**
+ * Update Setup Wizard flag in our DB.
+ *
+ * @since 2.6.0
+ *
+ * @param boolean $state A state (true/false) to set the is_setup_wizard_auth mailer setting.
+ */
+ public function update_is_setup_wizard_auth( $state ) {
+
+ $all = $this->connection_options->get_all();
+
+ // To save in DB.
+ $all[ $this->mailer_slug ]['is_setup_wizard_auth'] = (bool) $state;
+
+ // To save in currently retrieved options array.
+ $this->options['is_setup_wizard_auth'] = (bool) $state;
+
+ // NOTE: These options need to be saved by overwriting all options, because WP automatic updates can cause an issue: GH #575!
+ $this->connection_options->set( $all, false, true );
+ }
+
+ /**
+ * Update access token in our DB.
+ *
+ * @since 1.0.0
+ *
+ * @param mixed $token
+ */
+ protected function update_access_token( $token ) {
+
+ $all = $this->connection_options->get_all();
+
+ // To save in DB.
+ $all[ $this->mailer_slug ]['access_token'] = $token;
+
+ // To save in currently retrieved options array.
+ $this->options['access_token'] = $token;
+
+ // NOTE: These options need to be saved by overwriting all options, because WP automatic updates can cause an issue: GH #575!
+ $this->connection_options->set( $all, false, true );
+ }
+
+ /**
+ * Update refresh token in our DB.
+ *
+ * @since 1.0.0
+ *
+ * @param mixed $token
+ */
+ protected function update_refresh_token( $token ) {
+
+ $all = $this->connection_options->get_all();
+
+ // To save in DB.
+ $all[ $this->mailer_slug ]['refresh_token'] = $token;
+
+ // To save in currently retrieved options array.
+ $this->options['refresh_token'] = $token;
+
+ // NOTE: These options need to be saved by overwriting all options, because WP automatic updates can cause an issue: GH #575!
+ $this->connection_options->set( $all, false, true );
+ }
+
+ /**
+ * Update access token scopes in our DB.
+ *
+ * @since 3.4.0
+ *
+ * @param array $scopes Scopes array.
+ */
+ protected function update_scopes( $scopes ) {
+
+ $all = $this->connection_options->get_all();
+
+ // To save in DB.
+ $all[ $this->mailer_slug ]['scopes'] = $scopes;
+
+ // To save in currently retrieved options array.
+ $this->options['scopes'] = $scopes;
+
+ // NOTE: These options need to be saved by overwriting all options, because WP automatic updates can cause an issue: GH #575!
+ $this->connection_options->set( $all, false, true );
+ }
+
+ /**
+ * Get state value that should be used for `state` parameter in OAuth authorization request.
+ *
+ * @since 3.7.0
+ *
+ * @return string
+ */
+ protected function get_state() {
+
+ $state = [
+ wp_create_nonce( $this->state_key ),
+ $this->connection->get_id(),
+ ];
+
+ return implode( '-', $state );
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function is_clients_saved() {
+
+ return ! empty( $this->options['client_id'] ) && ! empty( $this->options['client_secret'] );
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function is_auth_required() {
+
+ return empty( $this->options['access_token'] ) || empty( $this->options['refresh_token'] );
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/src/Providers/AuthInterface.php b/wp-content/plugins/wp-mail-smtp/src/Providers/AuthInterface.php
new file mode 100755
index 00000000..9802c857
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/src/Providers/AuthInterface.php
@@ -0,0 +1,30 @@
+set_header( 'Accept', 'application/json' );
+ $this->set_header( 'Content-Type', 'application/json' );
+ $this->set_header( 'X-ElasticEmail-ApiKey', $this->connection_options->get( $this->mailer, 'api_key' ) );
+ }
+
+ /**
+ * Redefine the way custom headers are processed for this mailer - they should be in body.
+ *
+ * @since 4.3.0
+ *
+ * @param array $headers Headers array.
+ */
+ public function set_headers( $headers ) {
+
+ foreach ( $headers as $header ) {
+ $name = isset( $header[0] ) ? $header[0] : false;
+ $value = isset( $header[1] ) ? $header[1] : false;
+
+ $this->set_body_header( $name, $value );
+ }
+
+ // Add custom header.
+ $this->set_body_header( 'X-Mailer', 'WPMailSMTP/Mailer/' . $this->mailer . ' ' . WPMS_PLUGIN_VER );
+ }
+
+ /**
+ * This mailer supports email-related custom headers inside a body of the message.
+ *
+ * @since 4.3.0
+ *
+ * @param string $name Header name.
+ * @param string $value Header value.
+ */
+ public function set_body_header( $name, $value ) {
+
+ $name = sanitize_text_field( $name );
+
+ if ( empty( $name ) ) {
+ return;
+ }
+
+ $this->set_body_param(
+ [
+ 'Content' => [
+ 'Headers' => [
+ $name => $this->sanitize_header_value( $name, $value ),
+ ],
+ ],
+ ]
+ );
+ }
+
+ /**
+ * Set the From information for an email.
+ *
+ * @since 4.3.0
+ *
+ * @param string $email The sender email address.
+ * @param string $name The sender name.
+ */
+ public function set_from( $email, $name ) {
+
+ if ( ! filter_var( $email, FILTER_VALIDATE_EMAIL ) ) {
+ return;
+ }
+
+ $this->set_body_param(
+ [
+ 'Content' => [
+ 'From' => $this->address_format( [ $email, $name ] ),
+ ],
+ ]
+ );
+ }
+
+ /**
+ * Set email recipients: to, cc, bcc.
+ *
+ * @since 4.3.0
+ *
+ * @param array $recipients Email recipients.
+ */
+ public function set_recipients( $recipients ) { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh
+
+ if ( empty( $recipients ) ) {
+ return;
+ }
+
+ // Allow only these recipient types.
+ $recipient_mappings = [
+ 'to' => 'To',
+ 'cc' => 'CC',
+ 'bcc' => 'BCC',
+ ];
+
+ $allowed_types = array_keys( $recipient_mappings );
+ $data = [];
+
+ foreach ( $recipients as $type => $emails ) {
+ if (
+ ! in_array( $type, $allowed_types, true ) ||
+ empty( $emails ) ||
+ ! is_array( $emails )
+ ) {
+ continue;
+ }
+
+ $field = $recipient_mappings[ $type ];
+
+ // Iterate over all emails for each type.
+ // There might be multiple cc/to/bcc emails.
+ foreach ( $emails as $email ) {
+ if ( ! isset( $email[0] ) || ! filter_var( $email[0], FILTER_VALIDATE_EMAIL ) ) {
+ continue;
+ }
+
+ $data[ $field ][] = $this->address_format( $email );
+ }
+ }
+
+ if ( ! empty( $data ) ) {
+ $this->set_body_param(
+ [
+ 'Recipients' => $data,
+ ]
+ );
+ }
+ }
+
+ /**
+ * Set the Reply To information for an email.
+ *
+ * @since 4.3.0
+ *
+ * @param array $emails Reply To email addresses.
+ */
+ public function set_reply_to( $emails ) {
+
+ if ( empty( $emails ) ) {
+ return;
+ }
+
+ $data = [];
+
+ foreach ( $emails as $email ) {
+ if ( ! isset( $email[0] ) || ! filter_var( $email[0], FILTER_VALIDATE_EMAIL ) ) {
+ continue;
+ }
+
+ $data[] = $this->address_format( $email );
+ }
+
+ if ( ! empty( $data ) ) {
+ $this->set_body_param(
+ [
+ 'Content' => [
+ 'ReplyTo' => $data[0],
+ ],
+ ]
+ );
+ }
+ }
+
+ /**
+ * Set email subject.
+ *
+ * @since 4.3.0
+ *
+ * @param string $subject Email subject.
+ */
+ public function set_subject( $subject ) {
+
+ $this->set_body_param(
+ [
+ 'Content' => [
+ 'Subject' => $subject,
+ ],
+ ]
+ );
+ }
+
+ /**
+ * Set email content.
+ *
+ * @since 4.3.0
+ *
+ * @param string|array $content Email content.
+ */
+ public function set_content( $content ) {
+
+ if ( empty( $content ) ) {
+ return;
+ }
+
+ $data = [];
+
+ if ( is_array( $content ) ) {
+ if ( ! empty( $content['text'] ) ) {
+ $data[] = [
+ 'ContentType' => 'PlainText',
+ 'Content' => $content['text'],
+ ];
+ }
+
+ if ( ! empty( $content['html'] ) ) {
+ $data[] = [
+ 'ContentType' => 'HTML',
+ 'Content' => $content['html'],
+ ];
+ }
+ } else {
+ if ( $this->phpmailer->ContentType === 'text/plain' ) {
+ $data[] = [
+ 'ContentType' => 'PlainText',
+ 'Content' => $content,
+ ];
+ } else {
+ $data[] = [
+ 'ContentType' => 'HTML',
+ 'Content' => $content,
+ ];
+ }
+ }
+
+ $this->set_body_param(
+ [
+ 'Content' => [
+ 'Body' => $data,
+ ],
+ ]
+ );
+ }
+
+ /**
+ * Set attachments for an email.
+ *
+ * @since 4.3.0
+ *
+ * @param array $attachments Attachments array.
+ */
+ public function set_attachments( $attachments ) { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh
+
+ if ( empty( $attachments ) ) {
+ return;
+ }
+
+ $data = $this->prepare_attachments( $attachments );
+
+ if ( ! empty( $data ) ) {
+ $this->set_body_param(
+ [
+ 'Content' => [
+ 'Attachments' => $data,
+ ],
+ ]
+ );
+ }
+ }
+
+ /**
+ * Prepare attachments data for SendLayer API.
+ *
+ * @since 4.3.0
+ *
+ * @param array $attachments Array of attachments.
+ *
+ * @return array
+ */
+ protected function prepare_attachments( $attachments ) {
+
+ $data = [];
+
+ foreach ( $attachments as $attachment ) {
+ $file = $this->get_attachment_file_content( $attachment );
+
+ if ( $file === false ) {
+ continue;
+ }
+
+ $filetype = str_replace( ';', '', trim( $attachment[4] ) );
+
+ $data[] = [
+ 'Name' => empty( $attachment[2] ) ? 'file-' . wp_hash( microtime() ) . '.' . $filetype : trim( $attachment[2] ), // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
+ 'BinaryContent' => base64_encode( $file ),
+ 'ContentType' => $attachment[4],
+ ];
+ }
+
+ return $data;
+ }
+
+ /**
+ * Doesn't support this.
+ * So we do nothing.
+ *
+ * @since 4.3.0
+ *
+ * @param string $email Return Path email address.
+ */
+ public function set_return_path( $email ) {}
+
+ /**
+ * Redefine the way email body is returned.
+ * By default, we are sending an array of data.
+ * ElasticEmail requires a JSON, so we encode the body.
+ *
+ * @since 4.3.0
+ */
+ public function get_body() {
+
+ $body = parent::get_body();
+
+ return wp_json_encode( $body );
+ }
+
+ /**
+ * We might need to do something after the email was sent to the API.
+ * In this method we preprocess the response from the API.
+ *
+ * @since 4.3.0
+ *
+ * @param mixed $response Response data.
+ */
+ protected function process_response( $response ) {
+
+ parent::process_response( $response );
+
+ if (
+ ! is_wp_error( $response ) &&
+ ! empty( $this->response['body'] ) &&
+ ! empty( $this->response['body']->TransactionID )
+ ) {
+ $this->phpmailer->addCustomHeader( 'X-Msg-ID', $this->response['body']->TransactionID );
+ $this->verify_sent_status = true;
+ }
+ }
+
+ /**
+ * Whether the email is sent or not.
+ * We check response code and a non-empty `TransactionID` field in the response body.
+ *
+ * @since 4.3.0
+ *
+ * @return bool
+ */
+ public function is_email_sent() {
+
+ $is_sent = false;
+
+ if (
+ wp_remote_retrieve_response_code( $this->response ) === $this->email_sent_code &&
+ ! empty( $this->response['body'] ) &&
+ ! empty( $this->response['body']->TransactionID )
+ ) {
+ $is_sent = true;
+ }
+
+ // phpcs:disable WPForms.Comments.Since.MissingPhpDoc, WPForms.PHP.ValidateHooks.InvalidHookName
+
+ /** This filter is documented in src/Providers/MailerAbstract.php. */
+ return apply_filters( 'wp_mail_smtp_providers_mailer_is_email_sent', $is_sent, $this->mailer );
+ // phpcs:enable WPForms.Comments.Since.MissingPhpDoc, WPForms.PHP.ValidateHooks.InvalidHookName
+ }
+
+ /**
+ * Get an Elastic Email specific response with a helpful error.
+ *
+ * @since 4.3.0
+ *
+ * @return string
+ */
+ public function get_response_error() { // phpcs:ignore Generic.Metrics.NestingLevel.MaxExceeded, Generic.Metrics.CyclomaticComplexity.TooHigh
+
+ $error_text[] = $this->error_message;
+
+ if ( ! empty( $this->response ) ) {
+ $body = wp_remote_retrieve_body( $this->response );
+
+ // phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
+ if ( ! empty( $body->Error ) ) {
+ $error_text[] = Helpers::format_error_message( $body->Error );
+ } else {
+ $error_text[] = WP::wp_remote_get_response_error_message( $this->response );
+ }
+ // phpcs:enable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
+ }
+
+ return implode( WP::EOL, array_map( 'esc_textarea', array_filter( $error_text ) ) );
+ }
+
+ /**
+ * Whether the mailer has all its settings correctly set up and saved.
+ *
+ * @since 4.3.0
+ *
+ * @return bool
+ */
+ public function is_mailer_complete() {
+
+ $options = $this->connection_options->get_group( $this->mailer );
+
+ if ( ! empty( $options['api_key'] ) ) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Prepare address param.
+ *
+ * @since 4.3.0
+ *
+ * @param array $address Address array.
+ *
+ * @return array
+ */
+ private function address_format( $address ) {
+
+ $email = isset( $address[0] ) ? $address[0] : false;
+ $name = isset( $address[1] ) ? $address[1] : false;
+
+ $result = $email;
+
+ if ( ! empty( $name ) ) {
+ $result = "{$name} <{$email}>";
+ }
+
+ return $result;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/src/Providers/ElasticEmail/Options.php b/wp-content/plugins/wp-mail-smtp/src/Providers/ElasticEmail/Options.php
new file mode 100755
index 00000000..65667632
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/src/Providers/ElasticEmail/Options.php
@@ -0,0 +1,132 @@
+get_connections_manager()->get_primary_connection();
+ }
+
+ $description = sprintf(
+ wp_kses( /* translators: %1$s - URL to ElasticEmail.com site. */
+ __( 'Elastic Email is a cloud-based email marketing platform offering tools for email campaigns, automation, transactional emails, and analytics, designed for businesses of all sizes.
If you\'re just starting out, you can use Elastic Email\'s free plan to send emails to your account address from one of your verified email addresses. You don\'t need to use a credit card to try it out. When you\'re ready, you can upgrade to a higher plan.', 'wp-mail-smtp' ) .
+ '
+
+ mailer_slug !== Options::SLUG ) {
+ return;
+ }
+
+ $this->options = $this->connection_options->get_group( $this->mailer_slug );
+
+ if ( wp_mail_smtp()->is_pro() && ! empty( $this->options['one_click_setup_enabled'] ) ) {
+ return;
+ }
+
+ if ( $this->is_clients_saved() ) {
+ $this->include_vendor_lib();
+
+ $this->client = $this->get_client();
+ }
+ }
+
+ /**
+ * Get the url, that users will be redirected back to finish the OAuth process.
+ *
+ * @since 1.5.2 Returned to the old, pre-1.5, structure of the link to preserve BC.
+ *
+ * @param ConnectionInterface $connection The Connection object.
+ *
+ * @return string
+ */
+ public static function get_plugin_auth_url( $connection = null ) {
+
+ if ( is_null( $connection ) ) {
+ $connection = wp_mail_smtp()->get_connections_manager()->get_primary_connection();
+ }
+
+ $auth_url = apply_filters(
+ 'wp_mail_smtp_gmail_get_plugin_auth_url',
+ add_query_arg(
+ [
+ 'page' => Area::SLUG,
+ 'tab' => 'auth',
+ ],
+ admin_url( 'options-general.php' )
+ )
+ );
+
+ return add_query_arg( 'state', self::get_state_param( $connection ), $auth_url );
+ }
+
+ /**
+ * Init and get the Google Client object.
+ *
+ * @since 1.0.0
+ * @since 1.5.0 Add ability to apply custom options to the client via a filter.
+ *
+ * @param bool $force If the client should be forcefully reinitialized.
+ *
+ * @return Google_Client
+ */
+ public function get_client( $force = false ) { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.MaxExceeded
+
+ // Doesn't load client twice + gives ability to overwrite.
+ if ( ! empty( $this->client ) && ! $force ) {
+ return $this->client;
+ }
+
+ $this->include_vendor_lib();
+
+ $client = new Google_Client(
+ array(
+ 'client_id' => $this->options['client_id'],
+ 'client_secret' => $this->options['client_secret'],
+ 'redirect_uris' => array(
+ self::get_oauth_redirect_url(),
+ ),
+ )
+ );
+ $client->setApplicationName( 'WP Mail SMTP v' . WPMS_PLUGIN_VER );
+ $client->setAccessType( 'offline' );
+ $client->setPrompt( 'consent' );
+ $client->setIncludeGrantedScopes( false );
+ // We request only the sending capability, as it's what we only need to do.
+ $client->setScopes( array( Gmail::MAIL_GOOGLE_COM ) );
+ $client->setRedirectUri( self::get_oauth_redirect_url() );
+
+ // Set our custom logger to replace Monolog dependency.
+ $client->setLogger( new Logger() );
+
+ if ( self::use_self_oauth_redirect_url() ) {
+ $client->setState( self::get_state_param( $this->connection ) );
+ } else {
+ $client->setState( self::get_plugin_auth_url( $this->connection ) );
+ }
+
+ // Apply custom options to the client.
+ $client = apply_filters( 'wp_mail_smtp_providers_gmail_auth_get_client_custom_options', $client );
+
+ if (
+ $this->is_auth_required() &&
+ ! empty( $this->options['auth_code'] )
+ ) {
+ try {
+ $creds = $client->fetchAccessTokenWithAuthCode( $this->options['auth_code'] );
+ } catch ( Exception $e ) {
+ $creds['error'] = $e->getMessage();
+ }
+
+ // Bail if we have an error.
+ if ( ! empty( $creds['error'] ) ) {
+ if ( $creds['error'] === 'invalid_client' ) {
+ $creds['error'] .= PHP_EOL . esc_html__( 'Please make sure your Google Client ID and Secret in the plugin settings are valid. Save the settings and try the Authorization again.' , 'wp-mail-smtp' );
+ }
+
+ Debug::set(
+ 'Mailer: Gmail' . "\r\n" .
+ $creds['error']
+ );
+
+ return $client;
+ } else {
+ Debug::clear();
+ }
+
+ $this->update_access_token( $client->getAccessToken() );
+ $this->update_refresh_token( $client->getRefreshToken() );
+ $this->update_user_details( $client );
+
+ // Update the "from email" to the connected user's email.
+ if ( ! empty( $this->options['user_details']['email'] ) ) {
+ $this->connection_options->set(
+ [
+ 'mail' => [
+ 'from_email' => $this->options['user_details']['email'],
+ ],
+ ],
+ false,
+ false
+ );
+ }
+ }
+
+ if ( ! empty( $this->options['access_token'] ) ) {
+ $client->setAccessToken( $this->options['access_token'] );
+ }
+
+ // Refresh the token if it's expired.
+ if ( $client->isAccessTokenExpired() ) {
+ $refresh = $client->getRefreshToken();
+ if ( empty( $refresh ) && isset( $this->options['refresh_token'] ) ) {
+ $refresh = $this->options['refresh_token'];
+ }
+
+ if ( ! empty( $refresh ) ) {
+ try {
+ $creds = $client->fetchAccessTokenWithRefreshToken( $refresh );
+ } catch ( Exception $e ) {
+ $creds['error'] = $e->getMessage();
+ Debug::set(
+ 'Mailer: Gmail' . "\r\n" .
+ $e->getMessage()
+ );
+ }
+
+ // Bail if we have an error.
+ if ( ! empty( $creds['error'] ) ) {
+ return $client;
+ }
+
+ $this->update_access_token( $client->getAccessToken() );
+ $this->update_refresh_token( $client->getRefreshToken() );
+ }
+ }
+
+ return $client;
+ }
+
+ /**
+ * Get the auth code from the $_GET and save it.
+ * Redirect user back to settings with an error message, if failed.
+ *
+ * @since 1.0.0
+ */
+ public function process() { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.MaxExceeded
+
+ $redirect_url = ( new ConnectionSettings( $this->connection ) )->get_admin_page_url();
+ $is_setup_wizard_auth = ! empty( $this->options['is_setup_wizard_auth'] );
+
+ if ( $is_setup_wizard_auth ) {
+ $this->update_is_setup_wizard_auth( false );
+
+ $redirect_url = SetupWizard::get_site_url() . '#/step/configure_mailer/gmail';
+ }
+
+ if ( ! ( isset( $_GET['tab'] ) && $_GET['tab'] === 'auth' ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+ wp_safe_redirect( $redirect_url );
+ exit;
+ }
+
+ $state = isset( $_GET['state'] ) ? sanitize_key( $_GET['state'] ) : false;
+
+ if ( empty( $state ) ) {
+ wp_safe_redirect(
+ add_query_arg( 'error', 'oauth_invalid_state', $redirect_url )
+ );
+ }
+
+ list( $nonce ) = array_pad( explode( '-', $state ), 1, false );
+
+ // Verify the nonce that should be returned in the state parameter.
+ if ( ! wp_verify_nonce( $nonce, $this->state_key ) ) {
+ wp_safe_redirect(
+ add_query_arg(
+ 'error',
+ 'google_invalid_nonce',
+ $redirect_url
+ )
+ );
+ exit;
+ }
+
+ // We can't process without saved client_id/secret.
+ if ( ! $this->is_clients_saved() ) {
+ Debug::set(
+ esc_html__( 'There was an error while processing the Google authentication request. Please make sure that you have Client ID and Client Secret both valid and saved.', 'wp-mail-smtp' )
+ );
+ wp_safe_redirect(
+ add_query_arg(
+ 'error',
+ 'google_no_clients',
+ $redirect_url
+ )
+ );
+ exit;
+ }
+
+ $this->include_vendor_lib();
+
+ $code = '';
+ $scope = '';
+ $error = '';
+
+ if ( isset( $_GET['error'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+ $error = sanitize_key( $_GET['error'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+ }
+
+ // In case of any error: display a message to a user.
+ if ( ! empty( $error ) ) {
+ DebugEvents::add_debug(
+ sprintf( /* Translators: %s the error code passed from Google. */
+ esc_html__( 'There was an error while processing Google authorization: %s', 'wp-mail-smtp' ),
+ esc_html( $error )
+ )
+ );
+
+ wp_safe_redirect(
+ add_query_arg(
+ 'error',
+ 'google_' . $error,
+ $redirect_url
+ )
+ );
+ exit;
+ }
+
+ if ( isset( $_GET['code'] ) ) {
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
+ $code = urldecode( $_GET['code'] );
+ }
+
+ if ( isset( $_GET['scope'] ) ) {
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
+ $scope = $_GET['scope'];
+
+ if ( self::use_self_oauth_redirect_url() ) {
+ $scope = urldecode( $scope );
+ } else {
+ // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode
+ $scope = urldecode( base64_decode( $scope ) );
+ }
+ }
+
+ // Let's try to get the access token.
+ if (
+ ! empty( $code ) &&
+ (
+ $scope === Gmail::MAIL_GOOGLE_COM . ' ' . Gmail::GMAIL_SEND ||
+ $scope === Gmail::GMAIL_SEND . ' ' . Gmail::MAIL_GOOGLE_COM ||
+ $scope === Gmail::GMAIL_SEND ||
+ $scope === Gmail::MAIL_GOOGLE_COM
+ )
+ ) {
+ // Save the auth code. So Google_Client can reuse it to retrieve the access token.
+ $this->update_auth_code( $code );
+ } else {
+ DebugEvents::add_debug(
+ esc_html__( 'There was an error while processing Google authorization: missing code or scope parameter.', 'wp-mail-smtp' )
+ );
+
+ wp_safe_redirect(
+ add_query_arg(
+ 'error',
+ 'google_no_code_scope',
+ $redirect_url
+ )
+ );
+ exit;
+ }
+
+ Debug::clear();
+
+ $this->get_client( true );
+
+ $error = Debug::get_last();
+
+ if ( ! empty( $error ) ) {
+ wp_safe_redirect(
+ add_query_arg(
+ 'error',
+ 'google_unsuccessful_oauth',
+ $redirect_url
+ )
+ );
+ exit;
+ }
+
+ wp_safe_redirect(
+ add_query_arg(
+ 'success',
+ 'google_site_linked',
+ $redirect_url
+ )
+ );
+ exit;
+ }
+
+ /**
+ * Get the auth URL used to proceed to Provider to request access to send emails.
+ *
+ * @since 1.0.0
+ *
+ * @return string
+ */
+ public function get_auth_url() {
+
+ if (
+ ! empty( $this->client ) &&
+ class_exists( 'WPMailSMTP\Vendor\Google_Client', false ) &&
+ $this->client instanceof Google_Client
+ ) {
+ return filter_var( $this->client->createAuthUrl(), FILTER_SANITIZE_URL );
+ }
+
+ return '#';
+ }
+
+ /**
+ * Get and update user-related details (currently only email).
+ *
+ * @since 3.11.0
+ *
+ * @param Google_Client $client The Google Client object (optional).
+ */
+ private function update_user_details( $client = false ) {
+
+ if ( $client === false ) {
+ $client = $this->get_client();
+ }
+
+ $gmail = new Gmail( $client );
+
+ try {
+ $email = $gmail->users->getProfile( 'me' )->getEmailAddress();
+
+ $user_details = [
+ 'email' => $email,
+ ];
+
+ // To save in DB.
+ $updated_settings = [
+ $this->mailer_slug => [
+ 'user_details' => $user_details,
+ ],
+ ];
+
+ // To save in currently retrieved options array.
+ $this->options['user_details'] = $user_details;
+
+ $this->connection_options->set( $updated_settings, false, false );
+ } catch ( Exception $e ) { // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedCatch
+ // Do nothing.
+ }
+ }
+
+ /**
+ * Get user information (currently only email) that is associated with the current OAuth connection.
+ *
+ * @since 1.5.0
+ * @since 3.11.0 Switched to DB stored value instead of API call.
+ *
+ * @return array
+ */
+ public function get_user_info() {
+
+ /*
+ * We need to populate user data on the fly for old users who already performed
+ * authorization before we switched to DB stored value.
+ */
+ if ( ! isset( $this->options['user_details'] ) && ! $this->is_auth_required() ) {
+ $this->update_user_details();
+ }
+
+ return $this->connection_options->get( $this->mailer_slug, 'user_details' );
+ }
+
+ /**
+ * Get the registered email addresses that the user can use as the "from email".
+ *
+ * @since 2.2.0
+ *
+ * @return array The list of possible from email addresses.
+ */
+ public function get_user_possible_send_from_addresses() {
+
+ if ( isset( $this->aliases ) ) {
+ return $this->aliases;
+ }
+
+ $gmail = new Gmail( $this->get_client() );
+
+ try {
+
+ // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
+ $response = $gmail->users_settings_sendAs->listUsersSettingsSendAs( 'me' );
+
+ // phpcs:disable
+ $this->aliases = array_map(
+ function( $sendAsObject ) {
+ return $sendAsObject['sendAsEmail'];
+ },
+ (array) $response->getSendAs()
+ );
+ // phpcs:enable
+
+ } catch ( Exception $exception ) {
+ DebugEvents::add_debug(
+ sprintf( /* Translators: %s the error message. */
+ esc_html__( 'An error occurred when trying to get Gmail aliases: %s', 'wp-mail-smtp' ),
+ esc_html( $exception->getMessage() )
+ )
+ );
+
+ $this->aliases = [];
+ }
+
+ return $this->aliases;
+ }
+
+ /**
+ * Get the Google oAuth 2.0 redirect URL.
+ *
+ * This is the URL that Google will redirect after the access to the Gmail account is granted or rejected.
+ * The below endpoint will then redirect back to the user's WP site (to self::get_plugin_auth_url() URL).
+ *
+ * @since 2.5.0
+ *
+ * @return string
+ */
+ public static function get_oauth_redirect_url() {
+
+ if ( self::use_self_oauth_redirect_url() ) {
+ return remove_query_arg( 'state', self::get_plugin_auth_url() );
+ } else {
+ return 'https://connect.wpmailsmtp.com/google/';
+ }
+ }
+
+ /**
+ * Get the state parameter for the Google oAuth redirect URL.
+ *
+ * @since 3.10.0
+ *
+ * @param ConnectionInterface $connection The Connection object.
+ *
+ * @return string
+ */
+ private static function get_state_param( $connection ) {
+
+ $state = [
+ wp_create_nonce( 'wp_mail_smtp_provider_client_state' ),
+ $connection->get_id(),
+ ];
+
+ return implode( '-', $state );
+ }
+
+ /**
+ * Whether to use self website redirect URL for the Google oAuth.
+ *
+ * @since 3.10.0
+ *
+ * @return bool
+ */
+ private static function use_self_oauth_redirect_url() {
+
+ /**
+ * Filter whether to use self website redirect URL for the Google oAuth.
+ *
+ * @since 3.10.0
+ *
+ * @param bool $use Whether to use self website redirect URL for the Google oAuth.
+ */
+ return apply_filters( 'wp_mail_smtp_providers_gmail_auth_use_self_oauth_redirect_url', false );
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/src/Providers/Gmail/Logger.php b/wp-content/plugins/wp-mail-smtp/src/Providers/Gmail/Logger.php
new file mode 100755
index 00000000..79674ef8
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/src/Providers/Gmail/Logger.php
@@ -0,0 +1,176 @@
+log( LogLevel::EMERGENCY, $message, $context );
+ }
+
+ /**
+ * Action must be taken immediately.
+ *
+ * @since 4.7.0
+ *
+ * @param string $message The log message.
+ * @param array $context The log context.
+ */
+ public function alert( $message, array $context = [] ) {
+
+ $this->log( LogLevel::ALERT, $message, $context );
+ }
+
+ /**
+ * Critical conditions.
+ *
+ * @since 4.7.0
+ *
+ * @param string $message The log message.
+ * @param array $context The log context.
+ */
+ public function critical( $message, array $context = [] ) {
+
+ $this->log( LogLevel::CRITICAL, $message, $context );
+ }
+
+ /**
+ * Runtime errors that do not require immediate action but should typically
+ * be logged and monitored.
+ *
+ * @since 4.7.0
+ *
+ * @param string $message The log message.
+ * @param array $context The log context.
+ */
+ public function error( $message, array $context = [] ) {
+
+ $this->log( LogLevel::ERROR, $message, $context );
+ }
+
+ /**
+ * Exceptional occurrences that are not errors.
+ *
+ * @since 4.7.0
+ *
+ * @param string $message The log message.
+ * @param array $context The log context.
+ */
+ public function warning( $message, array $context = [] ) {
+
+ $this->log( LogLevel::WARNING, $message, $context );
+ }
+
+ /**
+ * Normal but significant events.
+ *
+ * @since 4.7.0
+ *
+ * @param string $message The log message.
+ * @param array $context The log context.
+ */
+ public function notice( $message, array $context = [] ) {
+
+ $this->log( LogLevel::NOTICE, $message, $context );
+ }
+
+ /**
+ * Interesting events.
+ *
+ * @since 4.7.0
+ *
+ * @param string $message The log message.
+ * @param array $context The log context.
+ */
+ public function info( $message, array $context = [] ) {
+
+ $this->log( LogLevel::INFO, $message, $context );
+ }
+
+ /**
+ * Detailed debug information.
+ *
+ * @since 4.7.0
+ *
+ * @param string $message The log message.
+ * @param array $context The log context.
+ */
+ public function debug( $message, array $context = [] ) {
+
+ $this->log( LogLevel::DEBUG, $message, $context );
+ }
+
+ /**
+ * Logs with an arbitrary level.
+ *
+ * @since 4.7.0
+ *
+ * @param mixed $level The log level.
+ * @param string $message The log message.
+ * @param array $context The log context.
+ */
+ public function log( $level, $message, array $context = [] ) {
+
+ // Only log errors and warnings to avoid spam.
+ if ( ! in_array( $level, [ LogLevel::ERROR, LogLevel::WARNING, LogLevel::CRITICAL, LogLevel::EMERGENCY, LogLevel::ALERT ], true ) ) {
+ return;
+ }
+
+ // Interpolate context values into the message placeholders.
+ $message = $this->interpolate( $message, $context );
+
+ // Format the log message.
+ $formatted_message = sprintf(
+ '[%s] Gmail API: %s',
+ strtoupper( $level ),
+ $message
+ );
+
+ // Use WP Mail SMTP's Debug class to log the message.
+ Debug::set( $formatted_message );
+ }
+
+ /**
+ * Interpolates context values into the message placeholders.
+ *
+ * @since 4.7.0
+ *
+ * @param string $message The message with placeholders.
+ * @param array $context The context array.
+ *
+ * @return string The interpolated message.
+ */
+ private function interpolate( $message, array $context = [] ) {
+
+ // Build a replacement array with braces around the context keys.
+ $replace = [];
+
+ foreach ( $context as $key => $val ) {
+ // Check that the value can be cast to string.
+ if ( ! is_array( $val ) && ( ! is_object( $val ) || method_exists( $val, '__toString' ) ) ) {
+ $replace[ '{' . $key . '}' ] = $val;
+ }
+ }
+
+ // Interpolate replacement values into the message and return.
+ return strtr( $message, $replace );
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/src/Providers/Gmail/Mailer.php b/wp-content/plugins/wp-mail-smtp/src/Providers/Gmail/Mailer.php
new file mode 100755
index 00000000..142063a6
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/src/Providers/Gmail/Mailer.php
@@ -0,0 +1,294 @@
+is_valid_phpmailer( $phpmailer ) ) {
+ return;
+ }
+
+ $this->phpmailer = $phpmailer;
+ }
+
+ /**
+ * Use Google API Services to send emails.
+ *
+ * @since 1.0.0
+ */
+ public function send() {
+
+ // Include the Google library.
+ require_once wp_mail_smtp()->plugin_path . '/vendor/autoload.php';
+
+ $auth = new Auth( $this->connection );
+ $message = new Message();
+
+ // Set the authorized Gmail email address as the "from email" if the set email is not on the list of aliases.
+ $possible_from_emails = $auth->get_user_possible_send_from_addresses();
+
+ if ( ! in_array( $this->phpmailer->From, $possible_from_emails, true ) ) {
+ $user_info = $auth->get_user_info();
+
+ if ( ! empty( $user_info['email'] ) ) {
+ $this->phpmailer->From = $user_info['email'];
+ $this->phpmailer->Sender = $user_info['email'];
+ }
+ }
+
+ try {
+ // Prepare a message for sending if any changes happened above.
+ $this->phpmailer->preSend();
+
+ // Get the raw MIME email using MailCatcher data. We need to make base64URL-safe string.
+ $base64 = str_replace(
+ [ '+', '/', '=' ],
+ [ '-', '_', '' ],
+ base64_encode( $this->phpmailer->getSentMIMEMessage() ) //phpcs:ignore
+ );
+
+ $message->setRaw( $base64 );
+
+ $service = new Gmail( $auth->get_client() );
+ $response = $service->users_messages->send( 'me', $message );
+
+ DebugEvents::add_debug(
+ esc_html__( 'An email request was sent to the Gmail API.', 'wp-mail-smtp' )
+ );
+
+ $this->process_response( $response );
+ } catch ( \Exception $e ) {
+ $this->error_message = $this->process_exception_message( $e->getMessage() );
+ }
+ }
+
+ /**
+ * Save response from the API to use it later.
+ *
+ * @since 1.0.0
+ * @since 1.5.0 Added action "wp_mail_smtp_providers_gmail_mailer_process_response" with $response.
+ *
+ * @param Message $response Instance of Gmail response.
+ */
+ protected function process_response( $response ) {
+
+ $this->response = $response;
+
+ if ( empty( $this->response ) || ! method_exists( $this->response, 'getId' ) ) {
+ $this->error_message = esc_html__( 'The response object is invalid (missing getId method).', 'wp-mail-smtp' );
+ } else {
+ $message_id = $this->response->getId();
+
+ if ( empty( $message_id ) ) {
+ $this->error_message = esc_html__( 'The email message ID is missing.', 'wp-mail-smtp' );
+ }
+ }
+
+ do_action( 'wp_mail_smtp_providers_gmail_mailer_process_response', $this->response, $this->phpmailer );
+ }
+
+ /**
+ * Check whether the email was sent.
+ *
+ * @since 1.0.0
+ *
+ * @return bool
+ */
+ public function is_email_sent() {
+
+ $is_sent = false;
+
+ if (
+ ! empty( $this->response ) &&
+ method_exists( $this->response, 'getId' ) &&
+ ! empty( $this->response->getId() )
+ ) {
+ $is_sent = true;
+ }
+
+ /** This filter is documented in src/Providers/MailerAbstract.php. */
+ return apply_filters( 'wp_mail_smtp_providers_mailer_is_email_sent', $is_sent, $this->mailer );
+ }
+
+ /**
+ * This method is relevant to SMTP and Pepipost.
+ * All other custom mailers should override it with own information.
+ *
+ * @since 1.2.0
+ *
+ * @return string
+ */
+ public function get_debug_info() { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.MaxExceeded
+
+ $gmail_text = array();
+
+ $gmail = $this->connection_options->get_group( 'gmail' );
+ $curl_ver = 'No';
+ if ( function_exists( 'curl_version' ) ) {
+ $curl = curl_version();
+ $curl_ver = $curl['version'];
+ }
+
+ $gmail_text[] = 'Client ID/Secret: ' . ( ! empty( $gmail['client_id'] ) && ! empty( $gmail['client_secret'] ) ? 'Yes' : 'No' );
+ $gmail_text[] = 'Auth Code: ' . ( ! empty( $gmail['auth_code'] ) ? 'Yes' : 'No' );
+ $gmail_text[] = 'Access Token: ' . ( ! empty( $gmail['access_token'] ) ? 'Yes' : 'No' );
+
+ $gmail_text[] = ' Server:';
+
+ $gmail_text[] = 'OpenSSL: ' . ( extension_loaded( 'openssl' ) && defined( 'OPENSSL_VERSION_TEXT' ) ? OPENSSL_VERSION_TEXT : 'No' );
+ $gmail_text[] = 'PHP.allow_url_fopen: ' . ( ini_get( 'allow_url_fopen' ) ? 'Yes' : 'No' );
+ $gmail_text[] = 'PHP.stream_socket_client(): ' . ( function_exists( 'stream_socket_client' ) ? 'Yes' : 'No' );
+ $gmail_text[] = 'PHP.fsockopen(): ' . ( function_exists( 'fsockopen' ) ? 'Yes' : 'No' );
+ $gmail_text[] = 'PHP.curl_version(): ' . $curl_ver;
+ if ( function_exists( 'apache_get_modules' ) ) {
+ $modules = apache_get_modules();
+ $gmail_text[] = 'Apache.mod_security: ' . ( in_array( 'mod_security', $modules, true ) || in_array( 'mod_security2', $modules, true ) ? 'Yes' : 'No' );
+ }
+ if ( function_exists( 'selinux_is_enabled' ) ) {
+ $gmail_text[] = 'OS.SELinux: ' . ( selinux_is_enabled() ? 'Yes' : 'No' );
+ }
+ if ( function_exists( 'grsecurity_is_enabled' ) ) {
+ $gmail_text[] = 'OS.grsecurity: ' . ( grsecurity_is_enabled() ? 'Yes' : 'No' );
+ }
+
+ return implode( ' ', $gmail_text );
+ }
+
+ /**
+ * Whether the mailer has all its settings correctly set up and saved.
+ *
+ * @since 1.4.0
+ *
+ * @return bool
+ */
+ public function is_mailer_complete() {
+
+ if ( ! $this->is_php_compatible() ) {
+ return false;
+ }
+
+ $auth = new Auth( $this->connection );
+
+ if (
+ $auth->is_clients_saved() &&
+ ! $auth->is_auth_required()
+ ) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Process the exception message and append additional explanation to it.
+ *
+ * @since 2.1.0
+ *
+ * @param mixed $message A string or an object with strings.
+ *
+ * @return string
+ */
+ protected function process_exception_message( $message ) {
+
+ // Transform the passed message to a string.
+ if ( ! is_string( $message ) ) {
+ $message = wp_json_encode( $message );
+ } else {
+ $message = wp_strip_all_tags( $message, false );
+ }
+
+ // Define known errors, that we will scan the message with.
+ $known_errors = [
+ [
+ 'errors' => [
+ 'invalid_grant',
+ ],
+ 'explanation' => esc_html__( 'Please re-grant Google app permissions!', 'wp-mail-smtp' ) . ' ' . WP::EOL .
+ esc_html__( 'Go to WP Mail SMTP plugin settings page. Click the āRemove OAuth Connectionā button.', 'wp-mail-smtp' ) . ' ' . WP::EOL .
+ esc_html__( 'Then click the āAllow plugin to send emails using your Google accountā button and re-enable access.', 'wp-mail-smtp' ),
+ ],
+ ];
+
+ // Check if we get a match and append the explanation to the original message.
+ foreach ( $known_errors as $error ) {
+ foreach ( $error['errors'] as $error_fragment ) {
+ if ( false !== strpos( $message, $error_fragment ) ) {
+ return Helpers::format_error_message( $message, '', $error['explanation'] );
+ }
+ }
+ }
+
+ // If we get no match we return the original message (as a string).
+ return $message;
+ }
+
+ /**
+ * Get the default email addresses for the reply to email parameter.
+ *
+ * @deprecated 2.1.1
+ *
+ * @since 2.1.0
+ * @since 2.1.1 Not used anymore.
+ *
+ * @return array
+ */
+ public function default_reply_to_addresses() {
+
+ _deprecated_function( __CLASS__ . '::' . __METHOD__, '2.1.1 of WP Mail SMTP plugin' );
+
+ $gmail_creds = ( new Auth( $this->connection ) )->get_user_info();
+
+ if ( empty( $gmail_creds['email'] ) ) {
+ return [];
+ }
+
+ return [
+ $gmail_creds['email'] => [
+ $gmail_creds['email'],
+ '',
+ ],
+ ];
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/src/Providers/Gmail/Options.php b/wp-content/plugins/wp-mail-smtp/src/Providers/Gmail/Options.php
new file mode 100755
index 00000000..12348ccb
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/src/Providers/Gmail/Options.php
@@ -0,0 +1,299 @@
+ wp_mail_smtp()->assets_url . '/images/providers/google.svg',
+ 'slug' => self::SLUG,
+ 'title' => esc_html__( 'Google / Gmail', 'wp-mail-smtp' ),
+ 'description' => sprintf(
+ wp_kses( /* translators: %s - URL to our Gmail doc. */
+ __( 'Our Gmail mailer works with any Gmail or Google Workspace account via the Google API. You can send WordPress emails from your main email address or a Gmail alias, and it\'s more secure than connecting to Gmail using SMTP credentials. We now have a One-Click Setup, which simply asks you to authorize your Google account to use our app and takes care of everything for you. Alternatively, you can connect manually, which involves several steps that are more technical than other mailer options, so we created a detailed guide to walk you through the process.
To get started, read our Gmail documentation.', 'wp-mail-smtp' ),
+ [
+ 'br' => [],
+ 'a' => [
+ 'href' => [],
+ 'rel' => [],
+ 'target' => [],
+ ],
+ ]
+ ),
+ esc_url( wp_mail_smtp()->get_utm_url( 'https://wpmailsmtp.com/docs/how-to-set-up-the-gmail-mailer-in-wp-mail-smtp/', 'Gmail documentation' ) )
+ ),
+ 'notices' => [
+ 'educational' => wp_kses(
+ __( 'The Gmail mailer works well for sites that send low numbers of emails. However, Gmail\'s API has rate limitations and a number of additional restrictions that can lead to challenges during setup.
If you expect to send a high volume of emails, or if you find that your web host is not compatible with the Gmail API restrictions, then we recommend considering a different mailer option.', 'wp-mail-smtp' ),
+ [
+ 'br' => [],
+ ]
+ ),
+ ],
+ 'php' => '5.6',
+ 'supports' => [
+ 'from_email' => true,
+ 'from_name' => true,
+ 'return_path' => false,
+ 'from_email_force' => true,
+ 'from_name_force' => true,
+ ],
+ ],
+ $connection
+ );
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function display_options() {
+
+ // Do not display options if PHP version is not correct.
+ if ( ! $this->is_php_correct() ) {
+ $this->display_php_warning();
+
+ return;
+ }
+ ?>
+
+ is_pro() ) : ?>
+
+
+ recommended, $this );
+ }
+
+ /**
+ * Whether this mailer is disabled or not.
+ * Used for displaying Pro mailers inside Lite plugin.
+ *
+ * @since 1.7.0
+ *
+ * @return bool
+ */
+ public function is_disabled() {
+
+ return (bool) apply_filters( 'wp_mail_smtp_providers_provider_is_disabled', $this->disabled, $this );
+ }
+
+ /**
+ * Check whether we can use this provider based on the PHP version.
+ * Valid for those, that use SDK.
+ *
+ * @since 1.0.0
+ *
+ * @return bool
+ */
+ public function is_php_correct() {
+ return version_compare( phpversion(), $this->php, '>=' );
+ }
+
+ /**
+ * Display a helpful message to those users, that are using an outdated version of PHP,
+ * which is not supported by the currently selected Provider.
+ *
+ * @since 1.0.0
+ */
+ protected function display_php_warning() {
+ ?>
+
+
+
+ connection_options->get_group( $this->mailer );
+
+ // Host and Port are the only really required options.
+ if (
+ ! empty( $options['host'] ) &&
+ ! empty( $options['port'] )
+ ) {
+ return true;
+ }
+
+ return false;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/src/Providers/SMTP/Options.php b/wp-content/plugins/wp-mail-smtp/src/Providers/SMTP/Options.php
new file mode 100755
index 00000000..d53bfe0e
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/src/Providers/SMTP/Options.php
@@ -0,0 +1,48 @@
+ wp_mail_smtp()->assets_url . '/images/providers/smtp.svg',
+ 'slug' => 'smtp',
+ 'title' => esc_html__( 'Other SMTP', 'wp-mail-smtp' ),
+ 'description' => sprintf(
+ wp_kses(
+ /* translators: %s - URL to SMTP documentation. */
+ __( 'The Other SMTP option lets you send emails through an SMTP server instead of using a provider\'s API. This is easy and convenient, but it\'s less secure than the other mailers. Please note that your provider may not allow you to send a large number of emails. In that case, please use a different mailer.
To get started, read our Other SMTP documentation.', 'wp-mail-smtp' ),
+ [
+ 'br' => [],
+ 'a' => [
+ 'href' => [],
+ 'rel' => [],
+ 'target' => [],
+ ],
+ ]
+ ),
+ esc_url( wp_mail_smtp()->get_utm_url( 'https://wpmailsmtp.com/docs/how-to-set-up-the-other-smtp-mailer-in-wp-mail-smtp/', 'Other SMTP documentation' ) )
+ ),
+ ],
+ $connection
+ );
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/src/Providers/SMTP2GO/Mailer.php b/wp-content/plugins/wp-mail-smtp/src/Providers/SMTP2GO/Mailer.php
new file mode 100755
index 00000000..a4d9ad16
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/src/Providers/SMTP2GO/Mailer.php
@@ -0,0 +1,508 @@
+set_header( 'X-Smtp2go-Api-Key', $this->connection_options->get( $this->mailer, 'api_key' ) );
+ $this->set_header( 'Accept', 'application/json' );
+ $this->set_header( 'Content-Type', 'application/json' );
+ }
+
+ /**
+ * Redefine the way custom headers are processed for this mailer - they should be in body.
+ *
+ * @since 4.1.0
+ *
+ * @param array $headers Headers array.
+ */
+ public function set_headers( $headers ) {
+
+ foreach ( $headers as $header ) {
+ $name = isset( $header[0] ) ? $header[0] : false;
+ $value = isset( $header[1] ) ? $header[1] : false;
+
+ $this->set_body_header( $name, $value );
+ }
+
+ // Add custom header.
+ $this->set_body_header( 'X-Mailer', 'WPMailSMTP/Mailer/' . $this->mailer . ' ' . WPMS_PLUGIN_VER );
+ }
+
+ /**
+ * This mailer supports email-related custom headers inside a body of the message.
+ *
+ * @since 4.1.0
+ *
+ * @param string $name Header name.
+ * @param string $value Header value.
+ */
+ public function set_body_header( $name, $value ) {
+
+ $name = sanitize_text_field( $name );
+
+ if ( empty( $name ) ) {
+ return;
+ }
+
+ $headers = isset( $this->body['custom_headers'] ) ? (array) $this->body['custom_headers'] : [];
+
+ // Index by key to remove duplicates.
+ $headers = wp_list_pluck( $headers, 'value', 'header' );
+
+ // Sanitize headers.
+ $headers[ $name ] = $this->sanitize_header_value( $name, $value );
+
+ // Turn headers into a list of header => value entries.
+ $data = array_reduce(
+ array_keys( $headers ),
+ function ( $data, $header ) use ( $headers ) {
+
+ $data[] = [
+ 'header' => $header,
+ 'value' => $headers[ $header ],
+ ];
+
+ return $data;
+ },
+ []
+ );
+
+ $this->body['custom_headers'] = $data;
+ }
+
+ /**
+ * Set the From information for an email.
+ *
+ * @since 4.1.0
+ *
+ * @param string $email The sender email address.
+ * @param string $name The sender name.
+ */
+ public function set_from( $email, $name ) {
+
+ if ( ! filter_var( $email, FILTER_VALIDATE_EMAIL ) ) {
+ return;
+ }
+
+ $this->set_body_param(
+ [
+ 'sender' => $this->address_format( [ $email, $name ] ),
+ ]
+ );
+ }
+
+ /**
+ * Set email recipients: to, cc, bcc.
+ *
+ * @since 4.1.0
+ *
+ * @param array $recipients Email recipients.
+ */
+ public function set_recipients( $recipients ) { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh
+
+ if ( empty( $recipients ) ) {
+ return;
+ }
+
+ // Allow only these recipient types.
+ $allowed_types = [ 'to', 'cc', 'bcc' ];
+ $data = [];
+
+ foreach ( $recipients as $type => $emails ) {
+ if (
+ ! in_array( $type, $allowed_types, true ) ||
+ empty( $emails ) ||
+ ! is_array( $emails )
+ ) {
+ continue;
+ }
+
+ // Iterate over all emails for each type.
+ // There might be multiple cc/to/bcc emails.
+ foreach ( $emails as $email ) {
+ if ( ! isset( $email[0] ) || ! filter_var( $email[0], FILTER_VALIDATE_EMAIL ) ) {
+ continue;
+ }
+
+ $data[ $type ][] = $this->address_format( $email );
+ }
+ }
+
+ if ( ! empty( $data ) ) {
+ $this->set_body_param( $data );
+ }
+ }
+
+ /**
+ * Set the Reply To information for an email.
+ *
+ * @since 4.1.1
+ *
+ * @param array $emails Reply To email addresses.
+ */
+ public function set_reply_to( $emails ) {
+
+ if ( empty( $emails ) ) {
+ return;
+ }
+
+ $data = [];
+
+ foreach ( $emails as $email ) {
+ if ( ! isset( $email[0] ) || ! filter_var( $email[0], FILTER_VALIDATE_EMAIL ) ) {
+ continue;
+ }
+
+ $data[] = $this->address_format( $email );
+ }
+
+ if ( ! empty( $data ) ) {
+ $this->set_body_header(
+ 'Reply-To',
+ implode( ',', $data )
+ );
+ }
+ }
+
+ /**
+ * Set email subject.
+ *
+ * @since 4.1.0
+ *
+ * @param string $subject Email subject.
+ */
+ public function set_subject( $subject ) {
+
+ $this->set_body_param(
+ [
+ 'subject' => $subject,
+ ]
+ );
+ }
+
+ /**
+ * Set email content.
+ *
+ * @since 4.1.0
+ *
+ * @param string|array $content Email content.
+ */
+ public function set_content( $content ) {
+
+ if ( empty( $content ) ) {
+ return;
+ }
+
+ if ( is_array( $content ) ) {
+ if ( ! empty( $content['text'] ) ) {
+ $this->set_body_param(
+ [
+ 'text_body' => $content['text'],
+ ]
+ );
+ }
+
+ if ( ! empty( $content['html'] ) ) {
+ $this->set_body_param(
+ [
+ 'html_body' => $content['html'],
+ ]
+ );
+ }
+ } else {
+ if ( $this->phpmailer->ContentType === 'text/plain' ) {
+ $this->set_body_param(
+ [
+ 'text_body' => $content,
+ ]
+ );
+ } else {
+ $this->set_body_param(
+ [
+ 'html_body' => $content,
+ ]
+ );
+ }
+ }
+ }
+
+ /**
+ * Set attachments for an email.
+ *
+ * @since 4.1.0
+ *
+ * @param array $attachments Attachments array.
+ */
+ public function set_attachments( $attachments ) { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh
+
+ if ( empty( $attachments ) ) {
+ return;
+ }
+
+ $data = [];
+
+ // Split attachments into "attachments" and "inlines" groups.
+ foreach ( $attachments as $attachment ) {
+ $mode = in_array( $attachment[6], [ 'inline', 'attachment' ], true ) ? $attachment[6] : 'attachment';
+
+ if ( $mode === 'inline' ) {
+ $data['inlines'][] = $attachment;
+ } else {
+ $data['attachments'][] = $attachment;
+ }
+ }
+
+ // Prepare attachments.
+ foreach ( $data as $disposition => $attachments ) {
+ $data[ $disposition ] = $this->prepare_attachments( $attachments );
+ }
+
+ if ( ! empty( $data ) ) {
+ $this->set_body_param( $data );
+ }
+ }
+
+ /**
+ * Doesn't support this.
+ * So we do nothing.
+ *
+ * @since 4.1.0
+ *
+ * @param string $email Return Path email address.
+ */
+ public function set_return_path( $email ) {}
+
+ /**
+ * Redefine the way email body is returned.
+ * By default, we are sending an array of data.
+ * SMTP2GO requires a JSON, so we encode the body.
+ *
+ * @since 4.1.0
+ */
+ public function get_body() {
+
+ $body = parent::get_body();
+
+ return wp_json_encode( $body );
+ }
+
+ /**
+ * Prepare attachments data.
+ *
+ * @since 4.1.0
+ *
+ * @param array $attachments Array of attachments.
+ *
+ * @return array
+ */
+ protected function prepare_attachments( $attachments ) {
+
+ $data = [];
+
+ foreach ( $attachments as $attachment ) {
+ $file = $this->get_attachment_file_content( $attachment );
+
+ if ( $file === false ) {
+ continue;
+ }
+
+ $filetype = str_replace( ';', '', trim( $attachment[4] ) );
+
+ $data[] = [
+ 'filename' => empty( $attachment[2] ) ? 'file-' . wp_hash( microtime() ) . '.' . $filetype : trim( $attachment[2] ),
+ // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
+ 'fileblob' => base64_encode( $file ),
+ 'mimetype' => $attachment[4],
+ ];
+ }
+
+ return $data;
+ }
+
+ /**
+ * We might need to do something after the email was sent to the API.
+ * In this method we preprocess the response from the API.
+ *
+ * @since 4.1.0
+ *
+ * @param mixed $response Response data.
+ */
+ protected function process_response( $response ) {
+
+ parent::process_response( $response );
+
+ if (
+ ! is_wp_error( $response ) &&
+ ! empty( $this->response['body']->data ) &&
+ ! empty( $this->response['body']->data->email_id )
+ ) {
+ $this->phpmailer->addCustomHeader( 'X-Msg-ID', $this->response['body']->data->email_id );
+ $this->verify_sent_status = true;
+ }
+ }
+
+ /**
+ * Whether the email is sent or not.
+ * We check response code and a non-empty `email_id` field in the response body.
+ *
+ * @since 4.1.0
+ *
+ * @return bool
+ */
+ public function is_email_sent() {
+
+ $is_sent = false;
+
+ if (
+ wp_remote_retrieve_response_code( $this->response ) === $this->email_sent_code &&
+ ! empty( $this->response['body']->data ) &&
+ ! empty( $this->response['body']->data->email_id )
+ ) {
+ $is_sent = true;
+ }
+
+ // phpcs:disable WPForms.Comments.Since.MissingPhpDoc, WPForms.PHP.ValidateHooks.InvalidHookName
+
+ /** This filter is documented in src/Providers/MailerAbstract.php. */
+ return apply_filters( 'wp_mail_smtp_providers_mailer_is_email_sent', $is_sent, $this->mailer );
+ // phpcs:enable WPForms.Comments.Since.MissingPhpDoc, WPForms.PHP.ValidateHooks.InvalidHookName
+ }
+
+ /**
+ * Get a SMTP2GO-specific response with a helpful error.
+ *
+ * @since 4.1.0
+ *
+ * @return string
+ */
+ public function get_response_error() { // phpcs:ignore Generic.Metrics.NestingLevel.MaxExceeded, Generic.Metrics.CyclomaticComplexity.TooHigh
+
+ $error_text = [
+ $this->error_message,
+ ];
+
+ if ( ! empty( $this->response ) ) {
+ $body = wp_remote_retrieve_body( $this->response );
+
+ if ( ! empty( $body->data ) ) {
+ if ( ! empty( $body->data->failures ) ) {
+ foreach ( $body->data->failures as $error ) {
+ $error_text[] = Helpers::format_error_message( $error );
+ }
+ }
+
+ if ( ! empty( $body->data->error ) ) {
+ $error_code = ! empty( $body->data->error_code ) ? $body->data->error_code : '';
+
+ $error_text[] = Helpers::format_error_message( $body->data->error, $error_code );
+ }
+
+ if ( ! empty( $body->data->field_validation_errors ) ) {
+ $message = '';
+ $code = '';
+
+ if ( ! empty( $body->data->field_validation_errors->message ) ) {
+ $message = $body->data->field_validation_errors->message;
+ }
+
+ if ( ! empty( $body->data->field_validation_errors->fieldname ) ) {
+ $code = $body->data->field_validation_errors->fieldname;
+ }
+
+ if ( ! empty( $message ) ) {
+ $error_text[] = Helpers::format_error_message( $message, $code );
+ }
+ }
+ } else {
+ $error_text[] = WP::wp_remote_get_response_error_message( $this->response );
+ }
+ }
+
+ return implode( WP::EOL, array_map( 'esc_textarea', array_filter( $error_text ) ) );
+ }
+
+ /**
+ * Whether the mailer has all its settings correctly set up and saved.
+ *
+ * @since 4.1.0
+ *
+ * @return bool
+ */
+ public function is_mailer_complete() {
+
+ $options = $this->connection_options->get_group( $this->mailer );
+
+ // API key is the only required option.
+ if ( ! empty( $options['api_key'] ) ) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Prepare address param.
+ *
+ * @since 4.1.0
+ *
+ * @param array $address Address array.
+ *
+ * @return array
+ */
+ private function address_format( $address ) {
+
+ $email = isset( $address[0] ) ? $address[0] : false;
+ $name = isset( $address[1] ) ? $address[1] : false;
+
+ $result = $email;
+
+ if ( ! empty( $name ) ) {
+ $result = "\"{$name}\" <{$email}>";
+ }
+
+ return $result;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/src/Providers/SMTP2GO/Options.php b/wp-content/plugins/wp-mail-smtp/src/Providers/SMTP2GO/Options.php
new file mode 100755
index 00000000..d15cc208
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/src/Providers/SMTP2GO/Options.php
@@ -0,0 +1,133 @@
+get_connections_manager()->get_primary_connection();
+ }
+
+ $description = sprintf(
+ wp_kses( /* translators: %1$s - URL to SMTP2GO.com site. */
+ __( 'SMTP2GO provides a robust and reliable email delivery service with global infrastructure, real-time analytics, and advanced security features. If you\'re just starting out, you can use SMTP2GO\'s free plan to send up to 1000 emails per month.', 'wp-mail-smtp' ) .
+ '
+
+ set_header( 'Authorization', 'Bearer ' . $this->connection_options->get( $this->mailer, 'api_key' ) );
+ $this->set_header( 'Accept', 'application/json' );
+ $this->set_header( 'content-type', 'application/json' );
+
+ // Set mailer specific body parameters.
+ $this->set_body_param(
+ array(
+ 'channel' => $this->connection_options->get( $this->mailer, 'channel' ),
+ )
+ );
+ }
+
+ /**
+ * Redefine the way email body is returned.
+ * By default we are sending an array of data.
+ * SMTP.com requires a JSON, so we encode the body.
+ *
+ * @since 2.0.0
+ */
+ public function get_body() {
+
+ $body = parent::get_body();
+
+ return wp_json_encode( $body );
+ }
+
+ /**
+ * Define the FROM (name and email).
+ *
+ * @since 2.0.0
+ *
+ * @param string $email From Email address.
+ * @param string $name From Name.
+ */
+ public function set_from( $email, $name = '' ) {
+
+ if ( ! filter_var( $email, FILTER_VALIDATE_EMAIL ) ) {
+ return;
+ }
+
+ $from['address'] = $email;
+
+ if ( ! empty( $name ) ) {
+ $from['name'] = $name;
+ }
+
+ $this->set_body_param(
+ array(
+ 'originator' => array(
+ 'from' => $from,
+ ),
+ )
+ );
+ }
+
+ /**
+ * Define the CC/BCC/TO (with names and emails).
+ *
+ * @since 2.0.0
+ *
+ * @param array $recipients
+ */
+ public function set_recipients( $recipients ) {
+
+ if ( empty( $recipients ) ) {
+ return;
+ }
+
+ // Allow only these recipient types.
+ $allowed_types = array( 'to', 'cc', 'bcc' );
+ $data = array();
+
+ foreach ( $recipients as $type => $emails ) {
+ if (
+ ! in_array( $type, $allowed_types, true ) ||
+ empty( $emails ) ||
+ ! is_array( $emails )
+ ) {
+ continue;
+ }
+
+ $data[ $type ] = array();
+
+ // Iterate over all emails for each type.
+ // There might be multiple cc/to/bcc emails.
+ foreach ( $emails as $email ) {
+ $holder = array();
+ $address = isset( $email[0] ) ? $email[0] : false;
+ $name = isset( $email[1] ) ? $email[1] : false;
+
+ if ( ! filter_var( $address, FILTER_VALIDATE_EMAIL ) ) {
+ continue;
+ }
+
+ $holder['address'] = $address;
+ if ( ! empty( $name ) ) {
+ $holder['name'] = $name;
+ }
+
+ array_push( $data[ $type ], $holder );
+ }
+ }
+
+ if ( ! empty( $data ) ) {
+ $this->set_body_param(
+ array(
+ 'recipients' => $data,
+ )
+ );
+ }
+ }
+
+ /**
+ * Set the email content.
+ *
+ * @since 2.0.0
+ *
+ * @param array|string $content String when text/plain, array otherwise.
+ */
+ public function set_content( $content ) { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh
+
+ if ( empty( $content ) ) {
+ return;
+ }
+
+ $parts = [];
+
+ if ( is_array( $content ) ) {
+ $allowed = [ 'text', 'html' ];
+
+ foreach ( $content as $type => $body ) {
+ if (
+ ! in_array( $type, $allowed, true ) ||
+ empty( $body )
+ ) {
+ continue;
+ }
+
+ $content_type = 'text/plain';
+ $content_value = $body;
+
+ if ( $type === 'html' ) {
+ $content_type = 'text/html';
+ }
+
+ $parts[] = [
+ 'type' => $content_type,
+ 'content' => $content_value,
+ 'charset' => $this->phpmailer->CharSet,
+ ];
+ }
+ } else {
+ $content_type = 'text/html';
+ $content_value = $content;
+
+ if ( $this->phpmailer->ContentType === 'text/plain' ) {
+ $content_type = 'text/plain';
+ }
+
+ $parts[] = [
+ 'type' => $content_type,
+ 'content' => $content_value,
+ 'charset' => $this->phpmailer->CharSet,
+ ];
+ }
+
+ $this->set_body_param(
+ [
+ 'body' => [
+ 'parts' => $parts,
+ ],
+ ]
+ );
+ }
+
+ /**
+ * Redefine the way custom headers are processed for this mailer - they should be in body.
+ *
+ * @since 2.0.0
+ *
+ * @param array $headers
+ */
+ public function set_headers( $headers ) {
+
+ foreach ( $headers as $header ) {
+ $name = isset( $header[0] ) ? $header[0] : false;
+ $value = isset( $header[1] ) ? $header[1] : false;
+
+ $this->set_body_header( $name, $value );
+ }
+
+ // Add custom PHPMailer-specific header.
+ $this->set_body_header( 'X-Mailer', 'WPMailSMTP/Mailer/' . $this->mailer . ' ' . WPMS_PLUGIN_VER );
+ }
+
+ /**
+ * This mailer supports email-related custom headers inside a body of the message.
+ *
+ * @since 2.0.0
+ *
+ * @param string $name
+ * @param string $value
+ */
+ public function set_body_header( $name, $value ) {
+
+ $name = sanitize_text_field( $name );
+ if ( empty( $name ) ) {
+ return;
+ }
+
+ $headers = isset( $this->body['custom_headers'] ) ? (array) $this->body['custom_headers'] : array();
+
+ $headers[ $name ] = $this->sanitize_header_value( $name, $value );
+
+ $this->set_body_param(
+ array(
+ 'custom_headers' => $headers,
+ )
+ );
+ }
+
+ /**
+ * SMTP.com accepts an array of attachments in body.attachments section of the JSON payload.
+ *
+ * @since 2.0.0
+ *
+ * @param array $attachments The array of attachments data.
+ */
+ public function set_attachments( $attachments ) {
+
+ if ( empty( $attachments ) ) {
+ return;
+ }
+
+ $data = [];
+
+ foreach ( $attachments as $attachment ) {
+ $file = $this->get_attachment_file_content( $attachment );
+
+ if ( $file === false ) {
+ continue;
+ }
+
+ $filetype = str_replace( ';', '', trim( $attachment[4] ) );
+
+ $data[] = [
+ 'content' => chunk_split( base64_encode( $file ) ), // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
+ 'type' => $filetype,
+ 'encoding' => 'base64',
+ 'filename' => $this->get_attachment_file_name( $attachment ),
+ 'disposition' => in_array( $attachment[6], [ 'inline', 'attachment' ], true ) ? $attachment[6] : 'attachment', // either inline or attachment.
+ 'cid' => empty( $attachment[7] ) ? '' : trim( (string) $attachment[7] ),
+ ];
+ }
+
+ if ( ! empty( $data ) ) {
+ $this->set_body_param(
+ [
+ 'body' => [
+ 'attachments' => $data,
+ ],
+ ]
+ );
+ }
+ }
+
+ /**
+ * Set Reply-To part of the message.
+ *
+ * @since 2.0.0
+ *
+ * @param array $reply_to
+ */
+ public function set_reply_to( $reply_to ) {
+
+ if ( empty( $reply_to ) ) {
+ return;
+ }
+
+ $data = array();
+
+ foreach ( $reply_to as $key => $emails ) {
+ if (
+ empty( $emails ) ||
+ ! is_array( $emails )
+ ) {
+ continue;
+ }
+
+ $address = isset( $emails[0] ) ? $emails[0] : false;
+ $name = isset( $emails[1] ) ? $emails[1] : false;
+
+ if ( ! filter_var( $address, FILTER_VALIDATE_EMAIL ) ) {
+ continue;
+ }
+
+ $data['address'] = $address;
+ if ( ! empty( $name ) ) {
+ $data['name'] = $name;
+ }
+
+ // Let the first valid email from the passed $reply_to serve as the reply_to parameter in STMP.com API.
+ // Only one email address and name is allowed in the `reply_to` parameter in the SMTP.com API payload.
+ break;
+ }
+
+ if ( ! empty( $data ) ) {
+ $this->set_body_param(
+ array(
+ 'originator' => array(
+ 'reply_to' => $data,
+ ),
+ )
+ );
+ }
+ }
+
+ /**
+ * SMTP.com doesn't support return_path params.
+ * So we do nothing.
+ *
+ * @since 2.0.0
+ *
+ * @param string $from_email
+ */
+ public function set_return_path( $from_email ) {}
+
+ /**
+ * We might need to do something after the email was sent to the API.
+ * In this method we preprocess the response from the API.
+ *
+ * @since 2.5.0
+ *
+ * @param mixed $response Response data.
+ */
+ protected function process_response( $response ) {
+
+ parent::process_response( $response );
+
+ if (
+ ! is_wp_error( $response ) &&
+ ! empty( $this->response['body']->data->message )
+ ) {
+ preg_match( '/msg_id: (.*)/', $this->response['body']->data->message, $output );
+
+ if ( ! empty( $output[1] ) ) {
+ $this->phpmailer->addCustomHeader( 'X-Msg-ID', $output[1] );
+ $this->verify_sent_status = true;
+ }
+ }
+ }
+
+ /**
+ * Get a SMTP.com-specific response with a helpful error.
+ *
+ * SMTP.com API error response (non 200 error code responses) is:
+ * {
+ * "status": "fail",
+ * "data": {
+ * "error_key": "short error message",
+ * }
+ * }
+ *
+ * It's good to combine the error_key and the message together for the best error explanation.
+ *
+ * @since 2.0.0
+ *
+ * @return string
+ */
+ public function get_response_error() {
+
+ $error_text[] = $this->error_message;
+
+ if ( ! empty( $this->response ) ) {
+ $body = wp_remote_retrieve_body( $this->response );
+
+ if ( ! empty( $body->data ) ) {
+ foreach ( (array) $body->data as $error_key => $error_message ) {
+ $error_text[] = Helpers::format_error_message( $error_message, $error_key );
+ }
+ } else {
+ $error_text[] = WP::wp_remote_get_response_error_message( $this->response );
+ }
+ }
+
+ return implode( WP::EOL, array_map( 'esc_textarea', array_filter( $error_text ) ) );
+ }
+
+ /**
+ * Get mailer debug information, that is helpful during support.
+ *
+ * @since 2.0.0
+ *
+ * @return string
+ */
+ public function get_debug_info() {
+
+ $options = $this->connection_options->get_group( $this->mailer );
+
+ $text[] = '' . esc_html__( 'Api Key:', 'wp-mail-smtp' ) . ' ' .
+ ( ! empty( $options['api_key'] ) ? 'Yes' : 'No' );
+ $text[] = '' . esc_html__( 'Channel:', 'wp-mail-smtp' ) . ' ' .
+ ( ! empty( $options['channel'] ) ? 'Yes' : 'No' );
+
+ return implode( ' ', $text );
+ }
+
+ /**
+ * Whether the mailer has all its settings correctly set up and saved.
+ *
+ * This mailer is configured when `api_key` and `channel` settings are defined.
+ *
+ * @since 2.0.0
+ *
+ * @return bool
+ */
+ public function is_mailer_complete() {
+
+ $options = $this->connection_options->get_group( $this->mailer );
+
+ if ( ! empty( $options['api_key'] ) && ! empty( $options['channel'] ) ) {
+ return true;
+ }
+
+ return false;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/src/Providers/SMTPcom/Options.php b/wp-content/plugins/wp-mail-smtp/src/Providers/SMTPcom/Options.php
new file mode 100755
index 00000000..94477d75
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/src/Providers/SMTPcom/Options.php
@@ -0,0 +1,174 @@
+get_connections_manager()->get_primary_connection();
+ }
+
+ $allowed_kses_html = array(
+ 'strong' => array(),
+ 'br' => array(),
+ 'a' => array(
+ 'href' => array(),
+ 'rel' => array(),
+ 'target' => array(),
+ ),
+ );
+
+ $description = sprintf(
+ wp_kses( /* translators: %s - URL to smtp.com site. */
+ __( 'SMTP.com is one of our recommended mailers. It\'s a transactional email provider that\'s currently used by 100,000+ businesses. SMTP.com is an established brand that\'s been offering email services for more than 20 years.
SMTP.com offers a free 30-day trial that allows you to send up to 50,000 emails.', 'wp-mail-smtp' ),
+ $allowed_kses_html
+ ),
+ 'https://wpmailsmtp.com/go/smtp/'
+ );
+ $description .= '
',
+ 'https://wpmailsmtp.com/go/smtp/',
+ esc_html__( 'Get Started with SMTP.com', 'wp-mail-smtp' )
+ );
+ }
+
+ $description .= '
' .
+ esc_html__( 'Transparency and Disclosure', 'wp-mail-smtp' ) .
+ '' .
+ esc_html__( 'We believe in full transparency. The SMTP.com links above are tracking links as part of our partnership with SMTP (j2 Global). We can recommend just about any SMTP service, but we only recommend products that we believe will add value to our users.', 'wp-mail-smtp' ) .
+ '
+
+ connection = $connection;
+ } else {
+ $this->connection = wp_mail_smtp()->get_connections_manager()->get_primary_connection();
+ }
+
+ $this->options = $this->connection->get_options()->get_group( Options::SLUG );
+ }
+
+ /**
+ * Configure API key authorization: api-key.
+ *
+ * @since 1.6.0
+ * @deprecated 3.9.0 We are no longer using the Sendinblue SDK.
+ *
+ * @return null
+ */
+ protected function get_api_config() {
+
+ _deprecated_function( __METHOD__, '3.9.0' );
+
+ return null;
+ }
+
+ /**
+ * Get the mailer client instance for Account API.
+ *
+ * @since 1.6.0
+ * @deprecated 3.9.0 We are no longer using the Sendinblue SDK.
+ */
+ public function get_account_client() {
+
+ _deprecated_function( __METHOD__, '3.9.0' );
+
+ return null;
+ }
+
+ /**
+ * Get the mailer client instance for Sender API.
+ *
+ * @since 1.6.0
+ * @deprecated 3.9.0 We are no longer using the Sendinblue SDK.
+ */
+ public function get_sender_client() {
+
+ _deprecated_function( __METHOD__, '3.9.0' );
+
+ return null;
+ }
+
+ /**
+ * Get the mailer client instance for SMTP API.
+ *
+ * @since 1.6.0
+ * @deprecated 3.9.0 We are no longer using the Sendinblue SDK.
+ */
+ public function get_smtp_client() {
+
+ _deprecated_function( __METHOD__, '3.9.0' );
+
+ return null;
+ }
+
+ /**
+ * Whether the mailer is ready to be used in API calls.
+ *
+ * @since 1.6.0
+ *
+ * @return bool
+ */
+ public function is_ready() {
+
+ return ! empty( $this->options['api_key'] );
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/src/Providers/Sendinblue/Mailer.php b/wp-content/plugins/wp-mail-smtp/src/Providers/Sendinblue/Mailer.php
new file mode 100755
index 00000000..9d308aba
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/src/Providers/Sendinblue/Mailer.php
@@ -0,0 +1,454 @@
+set_header( 'api-key', $this->connection_options->get( $this->mailer, 'api_key' ) );
+ $this->set_header( 'Accept', 'application/json' );
+ $this->set_header( 'content-type', 'application/json' );
+ }
+
+ /**
+ * The list of allowed attachment files extensions.
+ *
+ * @see https://developers.sendinblue.com/reference#sendTransacEmail_attachment__title
+ *
+ * @since 1.6.0
+ *
+ * @var array
+ */
+ // @formatter:off
+ protected $allowed_attach_ext = array( 'xlsx', 'xls', 'ods', 'docx', 'docm', 'doc', 'csv', 'pdf', 'txt', 'gif', 'jpg', 'jpeg', 'png', 'tif', 'tiff', 'rtf', 'bmp', 'cgm', 'css', 'shtml', 'html', 'htm', 'zip', 'xml', 'ppt', 'pptx', 'tar', 'ez', 'ics', 'mobi', 'msg', 'pub', 'eps', 'odt', 'mp3', 'm4a', 'm4v', 'wma', 'ogg', 'flac', 'wav', 'aif', 'aifc', 'aiff', 'mp4', 'mov', 'avi', 'mkv', 'mpeg', 'mpg', 'wmv' );
+ // @formatter:on
+
+ /**
+ * Redefine the way custom headers are processed for this mailer - they should be in body.
+ *
+ * @since 3.9.0
+ *
+ * @param array $headers List of key=>value pairs.
+ */
+ public function set_headers( $headers ) {
+
+ foreach ( $headers as $header ) {
+ $name = isset( $header[0] ) ? $header[0] : false;
+ $value = isset( $header[1] ) ? $header[1] : false;
+
+ $this->set_body_header( $name, $value );
+ }
+
+ // Add custom PHPMailer-specific header.
+ $this->set_body_header( 'X-Mailer', 'WPMailSMTP/Mailer/' . $this->mailer . ' ' . WPMS_PLUGIN_VER );
+ }
+
+ /**
+ * This mailer supports email-related custom headers inside a body of the message.
+ *
+ * @since 3.9.0
+ *
+ * @param string $name Key.
+ * @param string $value Value.
+ */
+ public function set_body_header( $name, $value ) {
+
+ $name = sanitize_text_field( $name );
+
+ if ( empty( $name ) ) {
+ return;
+ }
+
+ $headers = isset( $this->body['headers'] ) ? (array) $this->body['headers'] : [];
+ $headers[ $name ] = $this->sanitize_header_value( $name, $value );
+
+ $this->set_body_param(
+ [
+ 'headers' => $headers,
+ ]
+ );
+ }
+
+ /**
+ * Set the From information for an email.
+ *
+ * @since 1.6.0
+ *
+ * @param string $email
+ * @param string $name
+ */
+ public function set_from( $email, $name ) {
+
+ if ( ! filter_var( $email, FILTER_VALIDATE_EMAIL ) ) {
+ return;
+ }
+
+ $this->body['sender'] = array(
+ 'email' => $email,
+ 'name' => ! empty( $name ) ? WP::sanitize_value( $name ) : '',
+ );
+ }
+
+ /**
+ * Set email recipients: to, cc, bcc.
+ *
+ * @since 1.6.0
+ *
+ * @param array $recipients
+ */
+ public function set_recipients( $recipients ) {
+
+ if ( empty( $recipients ) ) {
+ return;
+ }
+
+ // Allow for now only these recipient types.
+ $default = array( 'to', 'cc', 'bcc' );
+ $data = array();
+
+ foreach ( $recipients as $type => $emails ) {
+
+ if (
+ ! in_array( $type, $default, true ) ||
+ empty( $emails ) ||
+ ! is_array( $emails )
+ ) {
+ continue;
+ }
+
+ $data[ $type ] = array();
+
+ // Iterate over all emails for each type.
+ // There might be multiple cc/to/bcc emails.
+ foreach ( $emails as $email ) {
+ $holder = array();
+ $addr = isset( $email[0] ) ? $email[0] : false;
+ $name = isset( $email[1] ) ? $email[1] : false;
+
+ if ( ! filter_var( $addr, FILTER_VALIDATE_EMAIL ) ) {
+ continue;
+ }
+
+ $holder['email'] = $addr;
+ if ( ! empty( $name ) ) {
+ $holder['name'] = $name;
+ }
+
+ array_push( $data[ $type ], $holder );
+ }
+ }
+
+ foreach ( $data as $type => $type_recipients ) {
+ $this->body[ $type ] = $type_recipients;
+ }
+ }
+
+ /**
+ * @inheritDoc
+ *
+ * @since 1.6.0
+ */
+ public function set_subject( $subject ) {
+
+ $this->body['subject'] = $subject;
+ }
+
+ /**
+ * Set email content.
+ *
+ * @since 1.6.0
+ *
+ * @param string|array $content
+ */
+ public function set_content( $content ) {
+
+ if ( empty( $content ) ) {
+ return;
+ }
+
+ if ( is_array( $content ) ) {
+
+ if ( ! empty( $content['text'] ) ) {
+ $this->body['textContent'] = $content['text'];
+ }
+
+ if ( ! empty( $content['html'] ) ) {
+ $this->body['htmlContent'] = $content['html'];
+ }
+ } else {
+ if ( $this->phpmailer->ContentType === 'text/plain' ) {
+ $this->body['textContent'] = $content;
+ } else {
+ $this->body['htmlContent'] = $content;
+ }
+ }
+ }
+
+ /**
+ * Doesn't support this.
+ *
+ * @since 1.6.0
+ *
+ * @param string $email
+ */
+ public function set_return_path( $email ) {
+
+ }
+
+ /**
+ * Set the Reply To headers if not set already.
+ *
+ * @since 1.6.0
+ *
+ * @param array $emails
+ */
+ public function set_reply_to( $emails ) {
+
+ if ( empty( $emails ) ) {
+ return;
+ }
+
+ $data = array();
+
+ foreach ( $emails as $user ) {
+ $holder = array();
+ $addr = isset( $user[0] ) ? $user[0] : false;
+ $name = isset( $user[1] ) ? $user[1] : false;
+
+ if ( ! filter_var( $addr, FILTER_VALIDATE_EMAIL ) ) {
+ continue;
+ }
+
+ $holder['email'] = $addr;
+ if ( ! empty( $name ) ) {
+ $holder['name'] = $name;
+ }
+
+ $data[] = $holder;
+ }
+
+ if ( ! empty( $data ) ) {
+ $this->body['replyTo'] = $data[0];
+ }
+ }
+
+ /**
+ * Set attachments for an email.
+ *
+ * @since 1.6.0
+ *
+ * @param array $attachments The array of attachments data.
+ */
+ public function set_attachments( $attachments ) {
+
+ if ( empty( $attachments ) ) {
+ return;
+ }
+
+ foreach ( $attachments as $attachment ) {
+
+ $ext = pathinfo( $attachment[1], PATHINFO_EXTENSION );
+
+ if ( ! in_array( $ext, $this->allowed_attach_ext, true ) ) {
+ continue;
+ }
+
+ $file = $this->get_attachment_file_content( $attachment );
+
+ if ( $file === false ) {
+ continue;
+ }
+
+ $this->body['attachment'][] = [
+ 'name' => $this->get_attachment_file_name( $attachment ),
+ 'content' => base64_encode( $file ), // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
+ ];
+ }
+ }
+
+ /**
+ * Get the email body.
+ *
+ * @since 1.6.0
+ * @since 3.9.0 Returns email body array instead of `SendSmtpEmail` object.
+ * @since 3.10.0 Returns JSON encoded email body instead of array.
+ *
+ * @return string
+ */
+ public function get_body() {
+
+ /**
+ * Filters Sendinblue email body.
+ *
+ * @since 3.5.0
+ *
+ * @param array $body Email body.
+ */
+ $body = apply_filters( 'wp_mail_smtp_providers_sendinblue_mailer_get_body', $this->body );
+
+ return wp_json_encode( $body );
+ }
+
+ /**
+ * We might need to do something after the email was sent to the API.
+ * In this method we preprocess the response from the API.
+ *
+ * @since 1.6.0
+ * @since 3.9.0 Expect a generic class object instead of `CreateSmtpEmail`.
+ *
+ * @param mixed $response Response from the API.
+ */
+ protected function process_response( $response ) {
+
+ parent::process_response( $response );
+
+ if ( $this->has_message_id() ) {
+ $this->phpmailer->MessageID = $this->response['body']->messageId;
+ $this->verify_sent_status = true;
+ }
+ }
+
+ /**
+ * Get a Sendinblue-specific response with a helpful error.
+ *
+ * @since 3.9.0
+ *
+ * @return string
+ */
+ public function get_response_error() {
+
+ $error_text = [];
+
+ if ( ! empty( $this->error_message ) ) {
+ $error_text[] = $this->error_message;
+ }
+
+ if ( ! empty( $this->response ) ) {
+ $body = wp_remote_retrieve_body( $this->response );
+
+ if ( ! empty( $body->message ) ) {
+ $error_text[] = Helpers::format_error_message( $body->message, ! empty( $body->code ) ? $body->code : '' );
+ } else {
+ $error_text[] = WP::wp_remote_get_response_error_message( $this->response );
+ }
+ }
+
+ return implode( WP::EOL, array_map( 'esc_textarea', array_filter( $error_text ) ) );
+ }
+
+ /**
+ * Check whether the response has `messageId` property.
+ *
+ * @since 3.9.0
+ *
+ * @return bool
+ */
+ private function has_message_id() {
+
+ if (
+ ! in_array(
+ wp_remote_retrieve_response_code( $this->response ),
+ [ $this->email_sent_code, $this->email_scheduled_code ],
+ true
+ ) ||
+ empty( $this->response['body']->messageId )
+ ) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Check whether the email was sent.
+ *
+ * @since 1.6.0
+ * @since 3.9.0 Check if `$this->response` has `messageId` property to check if the email was sent.
+ *
+ * @return bool
+ */
+ public function is_email_sent() {
+
+ /** This filter is documented in src/Providers/MailerAbstract.php. */
+ return apply_filters( 'wp_mail_smtp_providers_mailer_is_email_sent', $this->has_message_id(), $this->mailer ); // phpcs:ignore WPForms.PHP.ValidateHooks.InvalidHookName
+ }
+
+ /**
+ * @inheritdoc
+ *
+ * @since 1.6.0
+ */
+ public function get_debug_info() {
+
+ $mailjet_text[] = 'API Key: ' . ( $this->is_mailer_complete() ? 'Yes' : 'No' );
+
+ return implode( ' ', $mailjet_text );
+ }
+
+ /**
+ * @inheritdoc
+ *
+ * @since 1.6.0
+ */
+ public function is_mailer_complete() {
+
+ $options = $this->connection_options->get_group( $this->mailer );
+
+ // API key is the only required option.
+ if ( ! empty( $options['api_key'] ) ) {
+ return true;
+ }
+
+ return false;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/src/Providers/Sendinblue/Options.php b/wp-content/plugins/wp-mail-smtp/src/Providers/Sendinblue/Options.php
new file mode 100755
index 00000000..60c44109
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/src/Providers/Sendinblue/Options.php
@@ -0,0 +1,184 @@
+get_connections_manager()->get_primary_connection();
+ }
+
+ $description = sprintf(
+ wp_kses( /* translators: %1$s - URL to brevo.com site. */
+ __( 'Brevo (formerly Sendinblue) is one of our recommended mailers. It\'s a transactional email provider with scalable price plans, so it\'s suitable for any size of business.
If you\'re just starting out, you can use Brevo\'s free plan to send up to 300 emails a day. You don\'t need to use a credit card to try it out. When you\'re ready, you can upgrade to a higher plan to increase your sending limits.', 'wp-mail-smtp' ) .
+ '
' .
+ esc_html__( 'Transparency and Disclosure', 'wp-mail-smtp' ) .
+ '' .
+ esc_html__( 'We believe in full transparency. The Brevo (formerly Sendinblue) links above are tracking links as part of our partnership with Brevo. We can recommend just about any SMTP service, but we only recommend products that we believe will add value to our users.', 'wp-mail-smtp' ) .
+ '
+ $diff >= 0,
+ 'value' => round( $percent_change, 1 ),
+ ];
+ }
+
+ /**
+ * Set the HTML content type.
+ *
+ * @since 3.0.0
+ *
+ * @return string
+ */
+ public function set_html_content_type() {
+
+ return 'text/html';
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/src/Reports/Reports.php b/wp-content/plugins/wp-mail-smtp/src/Reports/Reports.php
new file mode 100755
index 00000000..1d90a003
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/src/Reports/Reports.php
@@ -0,0 +1,237 @@
+public_hooks();
+
+ if ( WP::in_wp_admin() ) {
+ $this->admin_hooks();
+ }
+ }
+
+ /**
+ * Frontend hooks.
+ *
+ * @since 3.0.0
+ */
+ private function public_hooks() {
+
+ // Update sent email counter when SMTP mailer is used.
+ add_action( 'wp_mail_smtp_mailcatcher_smtp_send_after', [ $this, 'update_sent_emails_stats' ] );
+
+ // Update sent email counter when all other mailers are used.
+ add_action( 'wp_mail_smtp_mailcatcher_send_after', [ $this, 'update_sent_emails_stats' ] );
+ }
+
+ /**
+ * Admin hooks.
+ *
+ * @since 3.0.0
+ */
+ private function admin_hooks() {
+
+ add_action( 'load-toplevel_page_wp-mail-smtp', [ $this, 'summary_report_email_preview' ] );
+
+ // Detect summary report email constant change.
+ if ( Options::init()->is_const_defined( 'general', SummaryReportEmail::SETTINGS_SLUG ) ) {
+ add_action( 'admin_init', [ $this, 'detect_summary_report_email_constant_change' ] );
+ }
+ }
+
+ /**
+ * Update all stats after email sent.
+ *
+ * @since 3.0.0
+ */
+ public function update_sent_emails_stats() {
+
+ if ( wp_mail_smtp()->is_pro() ) {
+ return;
+ }
+
+ $this->increment_sent_emails_counter();
+ $this->increment_weekly_sent_emails_counter();
+ }
+
+ /**
+ * Increment the number of total emails sent by 1.
+ *
+ * @since 3.0.0
+ */
+ private function increment_sent_emails_counter() {
+
+ $value = $this->get_total_emails_sent() + 1;
+
+ update_option( self::SENT_EMAILS_COUNTER_OPTION_KEY, $value, true );
+ }
+
+ /**
+ * Get the number of total emails sent.
+ *
+ * @since 3.0.0
+ *
+ * @return int
+ */
+ public function get_total_emails_sent() {
+
+ return get_option( self::SENT_EMAILS_COUNTER_OPTION_KEY, 0 );
+ }
+
+ /**
+ * Increment the number of total emails sent in this week by 1.
+ *
+ * @since 3.0.0
+ */
+ private function increment_weekly_sent_emails_counter() {
+
+ $stats = $this->get_total_weekly_emails_sent();
+
+ $week = $this->get_current_week();
+
+ if ( ! isset( $stats[ $week ] ) ) {
+ $stats[ $week ] = 0;
+ }
+
+ $stats[ $week ] ++;
+
+ // Cleanup old stats.
+ $stats = array_slice( $stats, self::WEEKLY_COUNTER_RETENTION_PERIOD * - 1, null, true );
+
+ update_option( self::WEEKLY_SENT_EMAILS_COUNTER_OPTION_KEY, $stats, true );
+ }
+
+ /**
+ * Get the number of total emails sent by week.
+ *
+ * @since 3.0.0
+ *
+ * @param int|string $week Week number or "now", "previous" identifiers.
+ *
+ * @return array|int
+ */
+ public function get_total_weekly_emails_sent( $week = null ) {
+
+ $stats = get_option( self::WEEKLY_SENT_EMAILS_COUNTER_OPTION_KEY, [] );
+
+ if ( ! is_null( $week ) ) {
+ if ( $week === 'now' ) {
+ $week = $this->get_current_week();
+ } elseif ( $week === 'previous' ) {
+ $week = $this->get_current_week() - 1;
+ }
+
+ return isset( $stats[ $week ] ) ? $stats[ $week ] : 0;
+ }
+
+ return $stats;
+ }
+
+ /**
+ * Generate a summary report email preview and display it for users.
+ *
+ * @since 3.0.0
+ */
+ public function summary_report_email_preview() {
+
+ if ( ! current_user_can( wp_mail_smtp()->get_admin()->get_logs_access_capability() ) ) {
+ return;
+ }
+
+ if ( ! isset( $_GET['mode'] ) || $_GET['mode'] !== 'summary_report_email_preview' ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+ return;
+ }
+
+ $email = $this->get_summary_report_email();
+
+ echo $email->get_content(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
+
+ exit;
+ }
+
+ /**
+ * Get emails stats weekly summary report email.
+ *
+ * @since 3.0.0
+ *
+ * @return SummaryReportEmail
+ */
+ public function get_summary_report_email() {
+
+ return new SummaryReportEmail();
+ }
+
+ /**
+ * Detect summary report email constant change.
+ *
+ * @since 3.0.0
+ */
+ public function detect_summary_report_email_constant_change() {
+
+ if ( ! WP::in_wp_admin() ) {
+ return;
+ }
+
+ if ( Options::init()->is_const_changed( 'general', SummaryReportEmail::SETTINGS_SLUG ) ) {
+ ( new SummaryEmailTask() )->cancel();
+ }
+ }
+
+ /**
+ * Get current week number.
+ *
+ * @since 3.0.0
+ *
+ * @return int
+ */
+ public function get_current_week() {
+
+ return current_time( 'W' );
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/src/SiteHealth.php b/wp-content/plugins/wp-mail-smtp/src/SiteHealth.php
new file mode 100755
index 00000000..5df48b9a
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/src/SiteHealth.php
@@ -0,0 +1,428 @@
+assets_url . '/css/admin-site-health.min.css',
+ false,
+ WPMS_PLUGIN_VER
+ );
+ }
+
+ /**
+ * Register plugin WP site health tests.
+ * This will be displayed in the "Status" tab of the WP Site Health page.
+ *
+ * @since 1.9.0
+ *
+ * @param array $tests The array with all WP site health tests.
+ *
+ * @return array
+ */
+ public function register_site_status_tests( $tests ) {
+
+ $tests['direct']['wp_mail_smtp_mailer_setup_complete'] = array(
+ 'label' => esc_html__( 'Is WP Mail SMTP mailer setup complete?', 'wp-mail-smtp' ),
+ 'test' => array( $this, 'mailer_setup_complete_test' ),
+ );
+
+ $tests['direct']['wp_mail_smtp_db_tables_exist'] = array(
+ 'label' => esc_html__( 'Do WP Mail SMTP DB tables exist?', 'wp-mail-smtp' ),
+ 'test' => [ $this, 'db_tables_test' ],
+ );
+
+ $tests['async']['wp_mail_smtp_email_domain_check'] = array(
+ 'label' => esc_html__( 'Is email domain configured properly?', 'wp-mail-smtp' ),
+ 'test' => 'email_domain_check_test',
+ );
+
+ return $tests;
+ }
+
+ /**
+ * Register plugin WP Site Health debug information.
+ * This will be displayed in the "Info" tab of the WP Site Health page.
+ *
+ * @since 1.9.0
+ *
+ * @param array $debug_info Array of existing debug information.
+ *
+ * @return array
+ */
+ public function register_debug_information( $debug_info ) {
+
+ $debug_notices = Debug::get();
+ $db_tables = $this->get_db_tables( 'existing' );
+
+ $debug_info[ self::DEBUG_INFO_SLUG ] = [
+ 'label' => $this->get_label(),
+ 'fields' => [
+ 'version' => [
+ 'label' => esc_html__( 'Version', 'wp-mail-smtp' ),
+ 'value' => WPMS_PLUGIN_VER,
+ ],
+ 'license_key_type' => [
+ 'label' => esc_html__( 'License key type', 'wp-mail-smtp' ),
+ 'value' => wp_mail_smtp()->get_license_type(),
+ ],
+ 'debug' => [
+ 'label' => esc_html__( 'Debug', 'wp-mail-smtp' ),
+ 'value' => ! empty( $debug_notices ) ? implode( '; ', $debug_notices ) : esc_html__( 'No debug notices found.', 'wp-mail-smtp' ),
+ ],
+ 'db_tables' => [
+ 'label' => esc_html__( 'DB tables', 'wp-mail-smtp' ),
+ 'value' => ! empty( $db_tables ) ?
+ implode( ', ', $db_tables ) : esc_html__( 'No DB tables found.', 'wp-mail-smtp' ),
+ 'private' => true,
+ ],
+ ],
+ ];
+
+ // Install date.
+ $activated = get_option( 'wp_mail_smtp_activated', [] );
+ if ( ! empty( $activated['lite'] ) ) {
+ $date = $activated['lite'] + ( get_option( 'gmt_offset' ) * 3600 );
+
+ $debug_info[ self::DEBUG_INFO_SLUG ]['fields']['lite_install_date'] = [
+ 'label' => esc_html__( 'Lite install date', 'wp-mail-smtp' ),
+ 'value' => date_i18n( esc_html__( 'M j, Y @ g:ia' ), $date ),
+ ];
+ }
+
+ return $debug_info;
+ }
+
+ /**
+ * Perform the WP site health test for checking, if the mailer setup is complete.
+ *
+ * @since 1.9.0
+ */
+ public function mailer_setup_complete_test() {
+
+ $mailer = Options::init()->get( 'mail', 'mailer' );
+ $mailer_complete = false;
+ $mailer_title = esc_html__( 'None selected', 'wp-mail-smtp' );
+
+ if ( ! empty( $mailer ) ) {
+ $mailer_object = wp_mail_smtp()
+ ->get_providers()
+ ->get_mailer(
+ $mailer,
+ wp_mail_smtp()->get_processor()->get_phpmailer()
+ );
+
+ $mailer_complete = ! empty( $mailer_object ) ? $mailer_object->is_mailer_complete() : false;
+
+ $mailer_title = wp_mail_smtp()->get_providers()->get_options( $mailer )->get_title();
+ }
+
+ // The default mailer should be considered as a non-complete mailer.
+ if ( $mailer === 'mail' ) {
+ $mailer_complete = false;
+ }
+
+ $mailer_text = sprintf(
+ '%s: %s',
+ esc_html__( 'Current mailer', 'wp-mail-smtp' ),
+ esc_html( $mailer_title )
+ );
+
+ $result = array(
+ 'label' => esc_html__( 'WP Mail SMTP mailer setup is complete', 'wp-mail-smtp' ),
+ 'status' => 'good',
+ 'badge' => array(
+ 'label' => $this->get_label(),
+ 'color' => self::BADGE_COLOR,
+ ),
+ 'description' => sprintf(
+ '
%s
%s
',
+ $mailer_text,
+ esc_html__( 'The WP Mail SMTP plugin mailer setup is complete. You can send a test email, to make sure it\'s working properly.', 'wp-mail-smtp' )
+ ),
+ 'actions' => sprintf(
+ '
',
+ esc_html__( 'You currently have the default mailer selected, which means that you havenāt set up SMTP yet.', 'wp-mail-smtp' )
+ );
+ }
+
+ if ( $mailer_complete === false ) {
+ $result['label'] = esc_html__( 'WP Mail SMTP mailer setup is incomplete', 'wp-mail-smtp' );
+ $result['status'] = 'recommended';
+ $result['badge']['color'] = 'orange';
+ $result['description'] = sprintf(
+ '
%s
%s
',
+ $mailer_text,
+ esc_html__( 'The WP Mail SMTP plugin mailer setup is incomplete. Please click on the link below to access plugin settings and configure the mailer.', 'wp-mail-smtp' )
+ );
+ $result['actions'] = sprintf(
+ '
',
+ esc_url( wp_mail_smtp()->get_admin()->get_admin_page_url() ),
+ esc_html__( 'Configure mailer', 'wp-mail-smtp' )
+ );
+ }
+
+ return $result;
+ }
+
+ /**
+ * Perform the test for checking if all custom plugin DB tables exist.
+ *
+ * @since 2.1.2
+ *
+ * @return array
+ */
+ public function db_tables_test() {
+
+ $result = array(
+ 'label' => esc_html__( 'WP Mail SMTP DB tables are created', 'wp-mail-smtp' ),
+ 'status' => 'good',
+ 'badge' => array(
+ 'label' => $this->get_label(),
+ 'color' => self::BADGE_COLOR,
+ ),
+ 'description' => esc_html__( 'WP Mail SMTP is using custom database tables for some of its features. In order to work properly, the custom tables should be created, and it looks like they exist in your database.', 'wp-mail-smtp' ),
+ 'actions' => '',
+ 'test' => 'wp_mail_smtp_db_tables_exist',
+ );
+
+ $missing_tables = $this->get_db_tables( 'missing' );
+
+ if ( ! empty( $missing_tables ) ) {
+ $missing_tables_create_link = wp_nonce_url(
+ add_query_arg(
+ [
+ 'create-missing-db-tables' => 1,
+ ],
+ wp_mail_smtp()->get_admin()->get_admin_page_url( Area::SLUG )
+ ),
+ Area::SLUG . '-create-missing-db-tables'
+ );
+
+ $result['label'] = esc_html__( 'WP Mail SMTP DB tables check has failed', 'wp-mail-smtp' );
+ $result['status'] = 'critical';
+ $result['badge']['color'] = 'red';
+ $result['description'] = sprintf(
+ '
%s
%s
',
+ sprintf( /* translators: %s - the list of missing tables separated by comma. */
+ esc_html( _n( 'Missing table: %s', 'Missing tables: %s', count( $missing_tables ), 'wp-mail-smtp' ) ),
+ esc_html( implode( ', ', $missing_tables ) )
+ ),
+ wp_kses(
+ sprintf( /* translators: %1$s - Settings Page URL; %2$s - The aria label; %3$s - The text that will appear on the link. */
+ __( 'WP Mail SMTP is using custom database tables for some of its features. In order to work properly, the custom tables should be created, and it seems they are missing. Please try to %3$s. If this issue persists, please contact our support.', 'wp-mail-smtp' ),
+ esc_url( $missing_tables_create_link ),
+ esc_attr__( 'Go to WP Mail SMTP settings page.', 'wp-mail-smtp' ),
+ esc_attr__( 'create the missing DB tables by clicking on this link', 'wp-mail-smtp' )
+ ),
+ [
+ 'a' => [
+ 'href' => [],
+ 'rel' => [],
+ 'target' => [],
+ 'aria-label' => [],
+ ],
+ ]
+ )
+ );
+ }
+
+ return $result;
+ }
+
+ /**
+ * Perform the test (async) for checking if email domain configured properly.
+ *
+ * @since 2.8.0
+ */
+ public function email_domain_check_test() {
+
+ check_ajax_referer( 'health-check-site-status' );
+
+ if ( ! current_user_can( 'view_site_health_checks' ) ) {
+ wp_send_json_error();
+ }
+
+ $options = Options::init();
+ $mailer = $options->get( 'mail', 'mailer' );
+ $email = $options->get( 'mail', 'from_email' );
+ $domain = '';
+
+ $email_domain_text = sprintf(
+ '%1$s: %2$s',
+ esc_html__( 'Current from email domain', 'wp-mail-smtp' ),
+ esc_html( WP::get_email_domain( $email ) )
+ );
+
+ $result = array(
+ 'label' => esc_html__( 'Email domain is configured correctly', 'wp-mail-smtp' ),
+ 'status' => 'good',
+ 'badge' => array(
+ 'label' => $this->get_label(),
+ 'color' => self::BADGE_COLOR,
+ ),
+ 'description' => sprintf(
+ '
%1$s
%2$s
',
+ $email_domain_text,
+ esc_html__( 'All checks for your email domain were successful. It looks like everything is configured correctly.', 'wp-mail-smtp' )
+ ),
+ 'actions' => sprintf(
+ '
' .
+ __( 'Action Scheduler is a scalable, traceable job queue for background processing large sets of actions. Action Scheduler works by triggering an action hook to run at some time in the future. Scheduled actions can also be scheduled to run on a recurring schedule.', 'action-scheduler' ) .
+ '
' .
+ esc_html__( 'Action Scheduler is currently being loaded from the following location. This can be useful when debugging, or if requested by the support team.', 'action-scheduler' ) .
+ '
';
+
+ return apply_filters( 'action_scheduler_list_table_column_args', $row_html, $row );
+ }
+
+ /**
+ * Prints the logs entries inline. We do so to avoid loading Javascript and other hacks to show it in a modal.
+ *
+ * @param array $row Action array.
+ * @return string
+ */
+ public function column_log_entries( array $row ) {
+
+ $log_entries_html = '';
+
+ $timezone = new DateTimezone( 'UTC' );
+
+ foreach ( $row['log_entries'] as $log_entry ) {
+ $log_entries_html .= $this->get_log_entry_html( $log_entry, $timezone );
+ }
+
+ $log_entries_html .= '';
+
+ return $log_entries_html;
+ }
+
+ /**
+ * Prints the logs entries inline. We do so to avoid loading Javascript and other hacks to show it in a modal.
+ *
+ * @param ActionScheduler_LogEntry $log_entry Log entry object.
+ * @param DateTimezone $timezone Timestamp.
+ * @return string
+ */
+ protected function get_log_entry_html( ActionScheduler_LogEntry $log_entry, DateTimezone $timezone ) {
+ $date = $log_entry->get_date();
+ $date->setTimezone( $timezone );
+ return sprintf( '
%s %s
', esc_html( $date->format( 'Y-m-d H:i:s O' ) ), esc_html( $log_entry->get_message() ) );
+ }
+
+ /**
+ * Only display row actions for pending actions.
+ *
+ * @param array $row Row to render.
+ * @param string $column_name Current row.
+ *
+ * @return string
+ */
+ protected function maybe_render_actions( $row, $column_name ) {
+ if ( 'pending' === strtolower( $row['status_name'] ) ) {
+ return parent::maybe_render_actions( $row, $column_name );
+ }
+
+ return '';
+ }
+
+ /**
+ * Renders admin notifications
+ *
+ * Notifications:
+ * 1. When the maximum number of tasks are being executed simultaneously.
+ * 2. Notifications when a task is manually executed.
+ * 3. Tables are missing.
+ */
+ public function display_admin_notices() {
+ global $wpdb;
+
+ if ( ( is_a( $this->store, 'ActionScheduler_HybridStore' ) || is_a( $this->store, 'ActionScheduler_DBStore' ) ) && apply_filters( 'action_scheduler_enable_recreate_data_store', true ) ) {
+ $table_list = array(
+ 'actionscheduler_actions',
+ 'actionscheduler_logs',
+ 'actionscheduler_groups',
+ 'actionscheduler_claims',
+ );
+
+ $found_tables = $wpdb->get_col( "SHOW TABLES LIKE '{$wpdb->prefix}actionscheduler%'" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
+ foreach ( $table_list as $table_name ) {
+ if ( ! in_array( $wpdb->prefix . $table_name, $found_tables, true ) ) {
+ $this->admin_notices[] = array(
+ 'class' => 'error',
+ 'message' => __( 'It appears one or more database tables were missing. Attempting to re-create the missing table(s).', 'action-scheduler' ),
+ );
+ $this->recreate_tables();
+ parent::display_admin_notices();
+
+ return;
+ }
+ }
+ }
+
+ if ( $this->runner->has_maximum_concurrent_batches() ) {
+ $claim_count = $this->store->get_claim_count();
+ $this->admin_notices[] = array(
+ 'class' => 'updated',
+ 'message' => sprintf(
+ /* translators: %s: amount of claims */
+ _n(
+ 'Maximum simultaneous queues already in progress (%s queue). No additional queues will begin processing until the current queues are complete.',
+ 'Maximum simultaneous queues already in progress (%s queues). No additional queues will begin processing until the current queues are complete.',
+ $claim_count,
+ 'action-scheduler'
+ ),
+ $claim_count
+ ),
+ );
+ } elseif ( $this->store->has_pending_actions_due() ) {
+
+ $async_request_lock_expiration = ActionScheduler::lock()->get_expiration( 'async-request-runner' );
+
+ // No lock set or lock expired.
+ if ( false === $async_request_lock_expiration || $async_request_lock_expiration < time() ) {
+ $in_progress_url = add_query_arg( 'status', 'in-progress', remove_query_arg( 'status' ) );
+ /* translators: %s: process URL */
+ $async_request_message = sprintf( __( 'A new queue has begun processing. View actions in-progress »', 'action-scheduler' ), esc_url( $in_progress_url ) );
+ } else {
+ /* translators: %d: seconds */
+ $async_request_message = sprintf( __( 'The next queue will begin processing in approximately %d seconds.', 'action-scheduler' ), $async_request_lock_expiration - time() );
+ }
+
+ $this->admin_notices[] = array(
+ 'class' => 'notice notice-info',
+ 'message' => $async_request_message,
+ );
+ }
+
+ $notification = get_transient( 'action_scheduler_admin_notice' );
+
+ if ( is_array( $notification ) ) {
+ delete_transient( 'action_scheduler_admin_notice' );
+
+ $action = $this->store->fetch_action( $notification['action_id'] );
+ $action_hook_html = '' . $action->get_hook() . '';
+
+ if ( 1 === absint( $notification['success'] ) ) {
+ $class = 'updated';
+ switch ( $notification['row_action_type'] ) {
+ case 'run':
+ /* translators: %s: action HTML */
+ $action_message_html = sprintf( __( 'Successfully executed action: %s', 'action-scheduler' ), $action_hook_html );
+ break;
+ case 'cancel':
+ /* translators: %s: action HTML */
+ $action_message_html = sprintf( __( 'Successfully canceled action: %s', 'action-scheduler' ), $action_hook_html );
+ break;
+ default:
+ /* translators: %s: action HTML */
+ $action_message_html = sprintf( __( 'Successfully processed change for action: %s', 'action-scheduler' ), $action_hook_html );
+ break;
+ }
+ } else {
+ $class = 'error';
+ /* translators: 1: action HTML 2: action ID 3: error message */
+ $action_message_html = sprintf( __( 'Could not process change for action: "%1$s" (ID: %2$d). Error: %3$s', 'action-scheduler' ), $action_hook_html, esc_html( $notification['action_id'] ), esc_html( $notification['error_message'] ) );
+ }
+
+ $action_message_html = apply_filters( 'action_scheduler_admin_notice_html', $action_message_html, $action, $notification );
+
+ $this->admin_notices[] = array(
+ 'class' => $class,
+ 'message' => $action_message_html,
+ );
+ }
+
+ parent::display_admin_notices();
+ }
+
+ /**
+ * Prints the scheduled date in a human friendly format.
+ *
+ * @param array $row The array representation of the current row of the table.
+ *
+ * @return string
+ */
+ public function column_schedule( $row ) {
+ return $this->get_schedule_display_string( $row['schedule'] );
+ }
+
+ /**
+ * Get the scheduled date in a human friendly format.
+ *
+ * @param ActionScheduler_Schedule $schedule Action's schedule.
+ * @return string
+ */
+ protected function get_schedule_display_string( ActionScheduler_Schedule $schedule ) {
+
+ $schedule_display_string = '';
+
+ if ( is_a( $schedule, 'ActionScheduler_NullSchedule' ) ) {
+ return __( 'async', 'action-scheduler' );
+ }
+
+ if ( ! method_exists( $schedule, 'get_date' ) || ! $schedule->get_date() ) {
+ return '0000-00-00 00:00:00';
+ }
+
+ $next_timestamp = $schedule->get_date()->getTimestamp();
+
+ $schedule_display_string .= $schedule->get_date()->format( 'Y-m-d H:i:s O' );
+ $schedule_display_string .= ' ';
+
+ if ( gmdate( 'U' ) > $next_timestamp ) {
+ /* translators: %s: date interval */
+ $schedule_display_string .= sprintf( __( ' (%s ago)', 'action-scheduler' ), self::human_interval( gmdate( 'U' ) - $next_timestamp ) );
+ } else {
+ /* translators: %s: date interval */
+ $schedule_display_string .= sprintf( __( ' (%s)', 'action-scheduler' ), self::human_interval( $next_timestamp - gmdate( 'U' ) ) );
+ }
+
+ return $schedule_display_string;
+ }
+
+ /**
+ * Bulk delete.
+ *
+ * Deletes actions based on their ID. This is the handler for the bulk delete. It assumes the data
+ * properly validated by the callee and it will delete the actions without any extra validation.
+ *
+ * @param int[] $ids Action IDs.
+ * @param string $ids_sql Inherited and unused.
+ */
+ protected function bulk_delete( array $ids, $ids_sql ) {
+ foreach ( $ids as $id ) {
+ try {
+ $this->store->delete_action( $id );
+ } catch ( Exception $e ) {
+ // A possible reason for an exception would include a scenario where the same action is deleted by a
+ // concurrent request.
+ // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
+ error_log(
+ sprintf(
+ /* translators: 1: action ID 2: exception message. */
+ __( 'Action Scheduler was unable to delete action %1$d. Reason: %2$s', 'action-scheduler' ),
+ $id,
+ $e->getMessage()
+ )
+ );
+ }
+ }
+ }
+
+ /**
+ * Implements the logic behind running an action. ActionScheduler_Abstract_ListTable validates the request and their
+ * parameters are valid.
+ *
+ * @param int $action_id Action ID.
+ */
+ protected function row_action_cancel( $action_id ) {
+ $this->process_row_action( $action_id, 'cancel' );
+ }
+
+ /**
+ * Implements the logic behind running an action. ActionScheduler_Abstract_ListTable validates the request and their
+ * parameters are valid.
+ *
+ * @param int $action_id Action ID.
+ */
+ protected function row_action_run( $action_id ) {
+ $this->process_row_action( $action_id, 'run' );
+ }
+
+ /**
+ * Force the data store schema updates.
+ */
+ protected function recreate_tables() {
+ if ( is_a( $this->store, 'ActionScheduler_HybridStore' ) ) {
+ $store = $this->store;
+ } else {
+ $store = new ActionScheduler_HybridStore();
+ }
+ add_action( 'action_scheduler/created_table', array( $store, 'set_autoincrement' ), 10, 2 );
+
+ $store_schema = new ActionScheduler_StoreSchema();
+ $logger_schema = new ActionScheduler_LoggerSchema();
+ $store_schema->register_tables( true );
+ $logger_schema->register_tables( true );
+
+ remove_action( 'action_scheduler/created_table', array( $store, 'set_autoincrement' ), 10 );
+ }
+ /**
+ * Implements the logic behind processing an action once an action link is clicked on the list table.
+ *
+ * @param int $action_id Action ID.
+ * @param string $row_action_type The type of action to perform on the action.
+ */
+ protected function process_row_action( $action_id, $row_action_type ) {
+ try {
+ switch ( $row_action_type ) {
+ case 'run':
+ $this->runner->process_action( $action_id, 'Admin List Table' );
+ break;
+ case 'cancel':
+ $this->store->cancel_action( $action_id );
+ break;
+ }
+ $success = 1;
+ $error_message = '';
+ } catch ( Exception $e ) {
+ $success = 0;
+ $error_message = $e->getMessage();
+ }
+
+ set_transient( 'action_scheduler_admin_notice', compact( 'action_id', 'success', 'error_message', 'row_action_type' ), 30 );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function prepare_items() {
+ $this->prepare_column_headers();
+
+ $per_page = $this->get_items_per_page( $this->get_per_page_option_name(), $this->items_per_page );
+
+ $query = array(
+ 'per_page' => $per_page,
+ 'offset' => $this->get_items_offset(),
+ 'status' => $this->get_request_status(),
+ 'orderby' => $this->get_request_orderby(),
+ 'order' => $this->get_request_order(),
+ 'search' => $this->get_request_search_query(),
+ );
+
+ /**
+ * Change query arguments to query for past-due actions.
+ * Past-due actions have the 'pending' status and are in the past.
+ * This is needed because registering 'past-due' as a status is overkill.
+ */
+ if ( 'past-due' === $this->get_request_status() ) {
+ $query['status'] = ActionScheduler_Store::STATUS_PENDING;
+ $query['date'] = as_get_datetime_object();
+ }
+
+ $this->items = array();
+
+ $total_items = $this->store->query_actions( $query, 'count' );
+
+ $status_labels = $this->store->get_status_labels();
+
+ foreach ( $this->store->query_actions( $query ) as $action_id ) {
+ try {
+ $action = $this->store->fetch_action( $action_id );
+ } catch ( Exception $e ) {
+ continue;
+ }
+ if ( is_a( $action, 'ActionScheduler_NullAction' ) ) {
+ continue;
+ }
+ $this->items[ $action_id ] = array(
+ 'ID' => $action_id,
+ 'hook' => $action->get_hook(),
+ 'status_name' => $this->store->get_status( $action_id ),
+ 'status' => $status_labels[ $this->store->get_status( $action_id ) ],
+ 'args' => $action->get_args(),
+ 'group' => $action->get_group(),
+ 'log_entries' => $this->logger->get_logs( $action_id ),
+ 'claim_id' => $this->store->get_claim_id( $action_id ),
+ 'recurrence' => $this->get_recurrence( $action ),
+ 'schedule' => $action->get_schedule(),
+ );
+ }
+
+ $this->set_pagination_args(
+ array(
+ 'total_items' => $total_items,
+ 'per_page' => $per_page,
+ 'total_pages' => ceil( $total_items / $per_page ),
+ )
+ );
+ }
+
+ /**
+ * Prints the available statuses so the user can click to filter.
+ */
+ protected function display_filter_by_status() {
+ $this->status_counts = $this->store->action_counts() + $this->store->extra_action_counts();
+ parent::display_filter_by_status();
+ }
+
+ /**
+ * Get the text to display in the search box on the list table.
+ */
+ protected function get_search_box_button_text() {
+ return __( 'Search hook, args and claim ID', 'action-scheduler' );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected function get_per_page_option_name() {
+ return str_replace( '-', '_', $this->screen->id ) . '_per_page';
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/ActionScheduler_LogEntry.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/ActionScheduler_LogEntry.php
new file mode 100755
index 00000000..726fea2e
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/ActionScheduler_LogEntry.php
@@ -0,0 +1,78 @@
+comment_type
+ * to ActionScheduler_LogEntry::__construct(), goodness knows why, and the Follow-up Emails plugin
+ * hard-codes loading its own version of ActionScheduler_wpCommentLogger with that out-dated method,
+ * goodness knows why, so we need to guard against that here instead of using a DateTime type declaration
+ * for the constructor's 3rd param of $date and causing a fatal error with older versions of FUE.
+ */
+ if ( null !== $date && ! is_a( $date, 'DateTime' ) ) {
+ _doing_it_wrong( __METHOD__, 'The third parameter must be a valid DateTime instance, or null.', '2.0.0' );
+ $date = null;
+ }
+
+ $this->action_id = $action_id;
+ $this->message = $message;
+ $this->date = $date ? $date : new Datetime();
+ }
+
+ /**
+ * Returns the date when this log entry was created
+ *
+ * @return Datetime
+ */
+ public function get_date() {
+ return $this->date;
+ }
+
+ /**
+ * Get action ID of log entry.
+ */
+ public function get_action_id() {
+ return $this->action_id;
+ }
+
+ /**
+ * Get log entry message.
+ */
+ public function get_message() {
+ return $this->message;
+ }
+}
+
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/ActionScheduler_NullLogEntry.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/ActionScheduler_NullLogEntry.php
new file mode 100755
index 00000000..4df0f05a
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/ActionScheduler_NullLogEntry.php
@@ -0,0 +1,18 @@
+maybe_dispatch_async_request() uses a lock to avoid
+ * calling ActionScheduler_QueueRunner->has_maximum_concurrent_batches() every time the 'shutdown',
+ * hook is triggered, because that method calls ActionScheduler_QueueRunner->store->get_claim_count()
+ * to find the current number of claims in the database.
+ *
+ * @param string $lock_type A string to identify different lock types.
+ * @bool True if lock value has changed, false if not or if set failed.
+ */
+ public function set( $lock_type ) {
+ global $wpdb;
+
+ $lock_key = $this->get_key( $lock_type );
+ $existing_lock_value = $this->get_existing_lock( $lock_type );
+ $new_lock_value = $this->new_lock_value( $lock_type );
+
+ // The lock may not exist yet, or may have been deleted.
+ if ( empty( $existing_lock_value ) ) {
+ return (bool) $wpdb->insert(
+ $wpdb->options,
+ array(
+ 'option_name' => $lock_key,
+ 'option_value' => $new_lock_value,
+ 'autoload' => 'no',
+ )
+ );
+ }
+
+ if ( $this->get_expiration_from( $existing_lock_value ) >= time() ) {
+ return false;
+ }
+
+ // Otherwise, try to obtain the lock.
+ return (bool) $wpdb->update(
+ $wpdb->options,
+ array( 'option_value' => $new_lock_value ),
+ array(
+ 'option_name' => $lock_key,
+ 'option_value' => $existing_lock_value,
+ )
+ );
+ }
+
+ /**
+ * If a lock is set, return the timestamp it was set to expiry.
+ *
+ * @param string $lock_type A string to identify different lock types.
+ * @return bool|int False if no lock is set, otherwise the timestamp for when the lock is set to expire.
+ */
+ public function get_expiration( $lock_type ) {
+ return $this->get_expiration_from( $this->get_existing_lock( $lock_type ) );
+ }
+
+ /**
+ * Given the lock string, derives the lock expiration timestamp (or false if it cannot be determined).
+ *
+ * @param string $lock_value String containing a timestamp, or pipe-separated combination of unique value and timestamp.
+ *
+ * @return false|int
+ */
+ private function get_expiration_from( $lock_value ) {
+ $lock_string = explode( '|', $lock_value );
+
+ // Old style lock?
+ if ( count( $lock_string ) === 1 && is_numeric( $lock_string[0] ) ) {
+ return (int) $lock_string[0];
+ }
+
+ // New style lock?
+ if ( count( $lock_string ) === 2 && is_numeric( $lock_string[1] ) ) {
+ return (int) $lock_string[1];
+ }
+
+ return false;
+ }
+
+ /**
+ * Get the key to use for storing the lock in the transient
+ *
+ * @param string $lock_type A string to identify different lock types.
+ * @return string
+ */
+ protected function get_key( $lock_type ) {
+ return sprintf( 'action_scheduler_lock_%s', $lock_type );
+ }
+
+ /**
+ * Supplies the existing lock value, or an empty string if not set.
+ *
+ * @param string $lock_type A string to identify different lock types.
+ *
+ * @return string
+ */
+ private function get_existing_lock( $lock_type ) {
+ global $wpdb;
+
+ // Now grab the existing lock value, if there is one.
+ return (string) $wpdb->get_var(
+ $wpdb->prepare(
+ "SELECT option_value FROM $wpdb->options WHERE option_name = %s",
+ $this->get_key( $lock_type )
+ )
+ );
+ }
+
+ /**
+ * Supplies a lock value consisting of a unique value and the current timestamp, which are separated by a pipe
+ * character.
+ *
+ * Example: (string) "649de012e6b262.09774912|1688068114"
+ *
+ * @param string $lock_type A string to identify different lock types.
+ *
+ * @return string
+ */
+ private function new_lock_value( $lock_type ) {
+ return uniqid( '', true ) . '|' . ( time() + $this->get_duration( $lock_type ) );
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/ActionScheduler_QueueCleaner.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/ActionScheduler_QueueCleaner.php
new file mode 100755
index 00000000..7029d0b2
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/ActionScheduler_QueueCleaner.php
@@ -0,0 +1,254 @@
+store = $store ? $store : ActionScheduler_Store::instance();
+ $this->batch_size = $batch_size;
+ }
+
+ /**
+ * Default queue cleaner process used by queue runner.
+ *
+ * @return array
+ */
+ public function delete_old_actions() {
+ /**
+ * Filter the minimum scheduled date age for action deletion.
+ *
+ * @param int $retention_period Minimum scheduled age in seconds of the actions to be deleted.
+ */
+ $lifespan = apply_filters( 'action_scheduler_retention_period', $this->month_in_seconds );
+
+ try {
+ $cutoff = as_get_datetime_object( $lifespan . ' seconds ago' );
+ } catch ( Exception $e ) {
+ _doing_it_wrong(
+ __METHOD__,
+ sprintf(
+ /* Translators: %s is the exception message. */
+ esc_html__( 'It was not possible to determine a valid cut-off time: %s.', 'action-scheduler' ),
+ esc_html( $e->getMessage() )
+ ),
+ '3.5.5'
+ );
+
+ return array();
+ }
+
+ /**
+ * Filter the statuses when cleaning the queue.
+ *
+ * @param string[] $default_statuses_to_purge Action statuses to clean.
+ */
+ $statuses_to_purge = (array) apply_filters( 'action_scheduler_default_cleaner_statuses', $this->default_statuses_to_purge );
+
+ return $this->clean_actions( $statuses_to_purge, $cutoff, $this->get_batch_size() );
+ }
+
+ /**
+ * Delete selected actions limited by status and date.
+ *
+ * @param string[] $statuses_to_purge List of action statuses to purge. Defaults to canceled, complete.
+ * @param DateTime $cutoff_date Date limit for selecting actions. Defaults to 31 days ago.
+ * @param int|null $batch_size Maximum number of actions per status to delete. Defaults to 20.
+ * @param string $context Calling process context. Defaults to `old`.
+ * @return array Actions deleted.
+ */
+ public function clean_actions( array $statuses_to_purge, DateTime $cutoff_date, $batch_size = null, $context = 'old' ) {
+ $batch_size = ! is_null( $batch_size ) ? $batch_size : $this->batch_size;
+ $cutoff = ! is_null( $cutoff_date ) ? $cutoff_date : as_get_datetime_object( $this->month_in_seconds . ' seconds ago' );
+ $lifespan = time() - $cutoff->getTimestamp();
+
+ if ( empty( $statuses_to_purge ) ) {
+ $statuses_to_purge = $this->default_statuses_to_purge;
+ }
+
+ $deleted_actions = array();
+
+ foreach ( $statuses_to_purge as $status ) {
+ $actions_to_delete = $this->store->query_actions(
+ array(
+ 'status' => $status,
+ 'modified' => $cutoff,
+ 'modified_compare' => '<=',
+ 'per_page' => $batch_size,
+ 'orderby' => 'none',
+ )
+ );
+
+ $deleted_actions = array_merge( $deleted_actions, $this->delete_actions( $actions_to_delete, $lifespan, $context ) );
+ }
+
+ return $deleted_actions;
+ }
+
+ /**
+ * Delete actions.
+ *
+ * @param int[] $actions_to_delete List of action IDs to delete.
+ * @param int $lifespan Minimum scheduled age in seconds of the actions being deleted.
+ * @param string $context Context of the delete request.
+ * @return array Deleted action IDs.
+ */
+ private function delete_actions( array $actions_to_delete, $lifespan = null, $context = 'old' ) {
+ $deleted_actions = array();
+
+ if ( is_null( $lifespan ) ) {
+ $lifespan = $this->month_in_seconds;
+ }
+
+ foreach ( $actions_to_delete as $action_id ) {
+ try {
+ $this->store->delete_action( $action_id );
+ $deleted_actions[] = $action_id;
+ } catch ( Exception $e ) {
+ /**
+ * Notify 3rd party code of exceptions when deleting a completed action older than the retention period
+ *
+ * This hook provides a way for 3rd party code to log or otherwise handle exceptions relating to their
+ * actions.
+ *
+ * @param int $action_id The scheduled actions ID in the data store
+ * @param Exception $e The exception thrown when attempting to delete the action from the data store
+ * @param int $lifespan The retention period, in seconds, for old actions
+ * @param int $count_of_actions_to_delete The number of old actions being deleted in this batch
+ * @since 2.0.0
+ */
+ do_action( "action_scheduler_failed_{$context}_action_deletion", $action_id, $e, $lifespan, count( $actions_to_delete ) );
+ }
+ }
+ return $deleted_actions;
+ }
+
+ /**
+ * Unclaim pending actions that have not been run within a given time limit.
+ *
+ * When called by ActionScheduler_Abstract_QueueRunner::run_cleanup(), the time limit passed
+ * as a parameter is 10x the time limit used for queue processing.
+ *
+ * @param int $time_limit The number of seconds to allow a queue to run before unclaiming its pending actions. Default 300 (5 minutes).
+ */
+ public function reset_timeouts( $time_limit = 300 ) {
+ $timeout = apply_filters( 'action_scheduler_timeout_period', $time_limit );
+
+ if ( $timeout < 0 ) {
+ return;
+ }
+
+ $cutoff = as_get_datetime_object( $timeout . ' seconds ago' );
+ $actions_to_reset = $this->store->query_actions(
+ array(
+ 'status' => ActionScheduler_Store::STATUS_PENDING,
+ 'modified' => $cutoff,
+ 'modified_compare' => '<=',
+ 'claimed' => true,
+ 'per_page' => $this->get_batch_size(),
+ 'orderby' => 'none',
+ )
+ );
+
+ foreach ( $actions_to_reset as $action_id ) {
+ $this->store->unclaim_action( $action_id );
+ do_action( 'action_scheduler_reset_action', $action_id );
+ }
+ }
+
+ /**
+ * Mark actions that have been running for more than a given time limit as failed, based on
+ * the assumption some uncatchable and unloggable fatal error occurred during processing.
+ *
+ * When called by ActionScheduler_Abstract_QueueRunner::run_cleanup(), the time limit passed
+ * as a parameter is 10x the time limit used for queue processing.
+ *
+ * @param int $time_limit The number of seconds to allow an action to run before it is considered to have failed. Default 300 (5 minutes).
+ */
+ public function mark_failures( $time_limit = 300 ) {
+ $timeout = apply_filters( 'action_scheduler_failure_period', $time_limit );
+
+ if ( $timeout < 0 ) {
+ return;
+ }
+
+ $cutoff = as_get_datetime_object( $timeout . ' seconds ago' );
+ $actions_to_reset = $this->store->query_actions(
+ array(
+ 'status' => ActionScheduler_Store::STATUS_RUNNING,
+ 'modified' => $cutoff,
+ 'modified_compare' => '<=',
+ 'per_page' => $this->get_batch_size(),
+ 'orderby' => 'none',
+ )
+ );
+
+ foreach ( $actions_to_reset as $action_id ) {
+ $this->store->mark_failure( $action_id );
+ do_action( 'action_scheduler_failed_action', $action_id, $timeout );
+ }
+ }
+
+ /**
+ * Do all of the cleaning actions.
+ *
+ * @param int $time_limit The number of seconds to use as the timeout and failure period. Default 300 (5 minutes).
+ */
+ public function clean( $time_limit = 300 ) {
+ $this->delete_old_actions();
+ $this->reset_timeouts( $time_limit );
+ $this->mark_failures( $time_limit );
+ }
+
+ /**
+ * Get the batch size for cleaning the queue.
+ *
+ * @return int
+ */
+ protected function get_batch_size() {
+ /**
+ * Filter the batch size when cleaning the queue.
+ *
+ * @param int $batch_size The number of actions to clean in one batch.
+ */
+ return absint( apply_filters( 'action_scheduler_cleanup_batch_size', $this->batch_size ) );
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/ActionScheduler_QueueRunner.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/ActionScheduler_QueueRunner.php
new file mode 100755
index 00000000..13a71e79
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/ActionScheduler_QueueRunner.php
@@ -0,0 +1,254 @@
+store );
+ }
+
+ $this->async_request = $async_request;
+ }
+
+ /**
+ * Initialize.
+ *
+ * @codeCoverageIgnore
+ */
+ public function init() {
+
+ add_filter( 'cron_schedules', array( self::instance(), 'add_wp_cron_schedule' ) ); // phpcs:ignore WordPress.WP.CronInterval.CronSchedulesInterval
+
+ // Check for and remove any WP Cron hook scheduled by Action Scheduler < 3.0.0, which didn't include the $context param.
+ $next_timestamp = wp_next_scheduled( self::WP_CRON_HOOK );
+ if ( $next_timestamp ) {
+ wp_unschedule_event( $next_timestamp, self::WP_CRON_HOOK );
+ }
+
+ $cron_context = array( 'WP Cron' );
+
+ if ( ! wp_next_scheduled( self::WP_CRON_HOOK, $cron_context ) ) {
+ $schedule = apply_filters( 'action_scheduler_run_schedule', self::WP_CRON_SCHEDULE );
+ wp_schedule_event( time(), $schedule, self::WP_CRON_HOOK, $cron_context );
+ }
+
+ add_action( self::WP_CRON_HOOK, array( self::instance(), 'run' ) );
+ $this->hook_dispatch_async_request();
+ }
+
+ /**
+ * Hook check for dispatching an async request.
+ */
+ public function hook_dispatch_async_request() {
+ add_action( 'shutdown', array( $this, 'maybe_dispatch_async_request' ) );
+ }
+
+ /**
+ * Unhook check for dispatching an async request.
+ */
+ public function unhook_dispatch_async_request() {
+ remove_action( 'shutdown', array( $this, 'maybe_dispatch_async_request' ) );
+ }
+
+ /**
+ * Check if we should dispatch an async request to process actions.
+ *
+ * This method is attached to 'shutdown', so is called frequently. To avoid slowing down
+ * the site, it mitigates the work performed in each request by:
+ * 1. checking if it's in the admin context and then
+ * 2. haven't run on the 'shutdown' hook within the lock time (60 seconds by default)
+ * 3. haven't exceeded the number of allowed batches.
+ *
+ * The order of these checks is important, because they run from a check on a value:
+ * 1. in memory - is_admin() maps to $GLOBALS or the WP_ADMIN constant
+ * 2. in memory - transients use autoloaded options by default
+ * 3. from a database query - has_maximum_concurrent_batches() run the query
+ * $this->store->get_claim_count() to find the current number of claims in the DB.
+ *
+ * If all of these conditions are met, then we request an async runner check whether it
+ * should dispatch a request to process pending actions.
+ */
+ public function maybe_dispatch_async_request() {
+ // Only start an async queue at most once every 60 seconds.
+ if (
+ is_admin()
+ && ! ActionScheduler::lock()->is_locked( 'async-request-runner' )
+ && ActionScheduler::lock()->set( 'async-request-runner' )
+ ) {
+ $this->async_request->maybe_dispatch();
+ }
+ }
+
+ /**
+ * Process actions in the queue. Attached to self::WP_CRON_HOOK i.e. 'action_scheduler_run_queue'
+ *
+ * The $context param of this method defaults to 'WP Cron', because prior to Action Scheduler 3.0.0
+ * that was the only context in which this method was run, and the self::WP_CRON_HOOK hook had no context
+ * passed along with it. New code calling this method directly, or by triggering the self::WP_CRON_HOOK,
+ * should set a context as the first parameter. For an example of this, refer to the code seen in
+ *
+ * @see ActionScheduler_AsyncRequest_QueueRunner::handle()
+ *
+ * @param string $context Optional identifier for the context in which this action is being processed, e.g. 'WP CLI' or 'WP Cron'
+ * Generally, this should be capitalised and not localised as it's a proper noun.
+ * @return int The number of actions processed.
+ */
+ public function run( $context = 'WP Cron' ) {
+ ActionScheduler_Compatibility::raise_memory_limit();
+ ActionScheduler_Compatibility::raise_time_limit( $this->get_time_limit() );
+ do_action( 'action_scheduler_before_process_queue' );
+ $this->run_cleanup();
+
+ $this->processed_actions_count = 0;
+ if ( false === $this->has_maximum_concurrent_batches() ) {
+ do {
+ $batch_size = apply_filters( 'action_scheduler_queue_runner_batch_size', 25 );
+ $processed_actions_in_batch = $this->do_batch( $batch_size, $context );
+ $this->processed_actions_count += $processed_actions_in_batch;
+ } while ( $processed_actions_in_batch > 0 && ! $this->batch_limits_exceeded( $this->processed_actions_count ) ); // keep going until we run out of actions, time, or memory.
+ }
+
+ do_action( 'action_scheduler_after_process_queue' );
+ return $this->processed_actions_count;
+ }
+
+ /**
+ * Process a batch of actions pending in the queue.
+ *
+ * Actions are processed by claiming a set of pending actions then processing each one until either the batch
+ * size is completed, or memory or time limits are reached, defined by @see $this->batch_limits_exceeded().
+ *
+ * @param int $size The maximum number of actions to process in the batch.
+ * @param string $context Optional identifier for the context in which this action is being processed, e.g. 'WP CLI' or 'WP Cron'
+ * Generally, this should be capitalised and not localised as it's a proper noun.
+ * @return int The number of actions processed.
+ */
+ protected function do_batch( $size = 100, $context = '' ) {
+ $claim = $this->store->stake_claim( $size );
+ $this->monitor->attach( $claim );
+ $processed_actions = 0;
+
+ foreach ( $claim->get_actions() as $action_id ) {
+ // bail if we lost the claim.
+ if ( ! in_array( $action_id, $this->store->find_actions_by_claim_id( $claim->get_id() ), true ) ) {
+ break;
+ }
+ $this->process_action( $action_id, $context );
+ $processed_actions++;
+
+ if ( $this->batch_limits_exceeded( $processed_actions + $this->processed_actions_count ) ) {
+ break;
+ }
+ }
+ $this->store->release_claim( $claim );
+ $this->monitor->detach();
+ $this->clear_caches();
+ return $processed_actions;
+ }
+
+ /**
+ * Flush the cache if possible (intended for use after a batch of actions has been processed).
+ *
+ * This is useful because running large batches can eat up memory and because invalid data can accrue in the
+ * runtime cache, which may lead to unexpected results.
+ */
+ protected function clear_caches() {
+ /*
+ * Calling wp_cache_flush_runtime() lets us clear the runtime cache without invalidating the external object
+ * cache, so we will always prefer this method (as compared to calling wp_cache_flush()) when it is available.
+ *
+ * However, this function was only introduced in WordPress 6.0. Additionally, the preferred way of detecting if
+ * it is supported changed in WordPress 6.1 so we use two different methods to decide if we should utilize it.
+ */
+ $flushing_runtime_cache_explicitly_supported = function_exists( 'wp_cache_supports' ) && wp_cache_supports( 'flush_runtime' );
+ $flushing_runtime_cache_implicitly_supported = ! function_exists( 'wp_cache_supports' ) && function_exists( 'wp_cache_flush_runtime' );
+
+ if ( $flushing_runtime_cache_explicitly_supported || $flushing_runtime_cache_implicitly_supported ) {
+ wp_cache_flush_runtime();
+ } elseif (
+ ! wp_using_ext_object_cache()
+ /**
+ * When an external object cache is in use, and when wp_cache_flush_runtime() is not available, then
+ * normally the cache will not be flushed after processing a batch of actions (to avoid a performance
+ * penalty for other processes).
+ *
+ * This filter makes it possible to override this behavior and always flush the cache, even if an external
+ * object cache is in use.
+ *
+ * @since 1.0
+ *
+ * @param bool $flush_cache If the cache should be flushed.
+ */
+ || apply_filters( 'action_scheduler_queue_runner_flush_cache', false )
+ ) {
+ wp_cache_flush();
+ }
+ }
+
+ /**
+ * Add schedule to WP cron.
+ *
+ * @param array> $schedules Schedules.
+ * @return array>
+ */
+ public function add_wp_cron_schedule( $schedules ) {
+ $schedules['every_minute'] = array(
+ 'interval' => 60, // in seconds.
+ 'display' => __( 'Every minute', 'action-scheduler' ),
+ );
+
+ return $schedules;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/ActionScheduler_RecurringActionScheduler.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/ActionScheduler_RecurringActionScheduler.php
new file mode 100755
index 00000000..2f393ffc
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/ActionScheduler_RecurringActionScheduler.php
@@ -0,0 +1,81 @@
+ 'plugin', # or 'theme'
+ * 'name' => 'Name',
+ * ]
+ *
+ * @return array
+ */
+ public static function active_source(): array {
+ $plugins = get_plugins();
+ $plugin_files = array_keys( $plugins );
+
+ foreach ( $plugin_files as $plugin_file ) {
+ $plugin_path = trailingslashit( WP_PLUGIN_DIR ) . dirname( $plugin_file );
+ $plugin_file = trailingslashit( WP_PLUGIN_DIR ) . $plugin_file;
+
+ if ( 0 !== strpos( dirname( __DIR__ ), $plugin_path ) ) {
+ continue;
+ }
+
+ $plugin_data = get_plugin_data( $plugin_file );
+
+ if ( ! is_array( $plugin_data ) || empty( $plugin_data['Name'] ) ) {
+ continue;
+ }
+
+ return array(
+ 'type' => 'plugin',
+ 'name' => $plugin_data['Name'],
+ );
+ }
+
+ $themes = (array) search_theme_directories();
+
+ foreach ( $themes as $slug => $data ) {
+ $needle = trailingslashit( $data['theme_root'] ) . $slug . '/';
+
+ if ( 0 !== strpos( __FILE__, $needle ) ) {
+ continue;
+ }
+
+ $theme = wp_get_theme( $slug );
+
+ if ( ! is_object( $theme ) || ! is_a( $theme, \WP_Theme::class ) ) {
+ continue;
+ }
+
+ return array(
+ 'type' => 'theme',
+ // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
+ 'name' => $theme->Name,
+ );
+ }
+
+ return array();
+ }
+
+ /**
+ * Returns the directory path for the currently active installation of Action Scheduler.
+ *
+ * @return string
+ */
+ public static function active_source_path(): string {
+ return trailingslashit( dirname( __DIR__ ) );
+ }
+
+ /**
+ * Get registered sources.
+ *
+ * It is not always possible to obtain this information. For instance, if earlier versions (<=3.9.0) of
+ * Action Scheduler register themselves first, then the necessary data about registered sources will
+ * not be available.
+ *
+ * @return array
+ */
+ public static function get_sources() {
+ $versions = ActionScheduler_Versions::instance();
+ return method_exists( $versions, 'get_sources' ) ? $versions->get_sources() : array();
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/ActionScheduler_Versions.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/ActionScheduler_Versions.php
new file mode 100755
index 00000000..c23e464a
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/ActionScheduler_Versions.php
@@ -0,0 +1,151 @@
+
+ */
+ private $versions = array();
+
+ /**
+ * Registered sources.
+ *
+ * @var array
+ */
+ private $sources = array();
+
+ /**
+ * Register version's callback.
+ *
+ * @param string $version_string Action Scheduler version.
+ * @param callable $initialization_callback Callback to initialize the version.
+ */
+ public function register( $version_string, $initialization_callback ) {
+ if ( isset( $this->versions[ $version_string ] ) ) {
+ return false;
+ }
+
+ // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_debug_backtrace
+ $backtrace = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS );
+ $source = $backtrace[0]['file'];
+
+ $this->versions[ $version_string ] = $initialization_callback;
+ $this->sources[ $source ] = $version_string;
+ return true;
+ }
+
+ /**
+ * Get all versions.
+ */
+ public function get_versions() {
+ return $this->versions;
+ }
+
+ /**
+ * Get registered sources.
+ *
+ * Use with caution: this method is only available as of Action Scheduler's 3.9.1
+ * release and, owing to the way Action Scheduler is loaded, it's possible that the
+ * class definition used at runtime will belong to an earlier version.
+ *
+ * @since 3.9.1
+ *
+ * @return array
+ */
+ public function get_sources() {
+ return $this->sources;
+ }
+
+ /**
+ * Get latest version registered.
+ */
+ public function latest_version() {
+ $keys = array_keys( $this->versions );
+ if ( empty( $keys ) ) {
+ return false;
+ }
+ uasort( $keys, 'version_compare' );
+ return end( $keys );
+ }
+
+ /**
+ * Get callback for latest registered version.
+ */
+ public function latest_version_callback() {
+ $latest = $this->latest_version();
+
+ if ( empty( $latest ) || ! isset( $this->versions[ $latest ] ) ) {
+ return '__return_null';
+ }
+
+ return $this->versions[ $latest ];
+ }
+
+ /**
+ * Get instance.
+ *
+ * @return ActionScheduler_Versions
+ * @codeCoverageIgnore
+ */
+ public static function instance() {
+ if ( empty( self::$instance ) ) {
+ self::$instance = new self();
+ }
+ return self::$instance;
+ }
+
+ /**
+ * Initialize.
+ *
+ * @codeCoverageIgnore
+ */
+ public static function initialize_latest_version() {
+ $self = self::instance();
+ call_user_func( $self->latest_version_callback() );
+ }
+
+ /**
+ * Returns information about the plugin or theme which contains the current active version
+ * of Action Scheduler.
+ *
+ * If this cannot be determined, or if Action Scheduler is being loaded via some other
+ * method, then it will return an empty array. Otherwise, if populated, the array will
+ * look like the following:
+ *
+ * [
+ * 'type' => 'plugin', # or 'theme'
+ * 'name' => 'Name',
+ * ]
+ *
+ * @deprecated 3.9.2 Use ActionScheduler_SystemInformation::active_source().
+ *
+ * @return array
+ */
+ public function active_source(): array {
+ _deprecated_function( __METHOD__, '3.9.2', 'ActionScheduler_SystemInformation::active_source()' );
+ return ActionScheduler_SystemInformation::active_source();
+ }
+
+ /**
+ * Returns the directory path for the currently active installation of Action Scheduler.
+ *
+ * @deprecated 3.9.2 Use ActionScheduler_SystemInformation::active_source_path().
+ *
+ * @return string
+ */
+ public function active_source_path(): string {
+ _deprecated_function( __METHOD__, '3.9.2', 'ActionScheduler_SystemInformation::active_source_path()' );
+ return ActionScheduler_SystemInformation::active_source_path();
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/ActionScheduler_WPCommentCleaner.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/ActionScheduler_WPCommentCleaner.php
new file mode 100755
index 00000000..2725d1fe
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/ActionScheduler_WPCommentCleaner.php
@@ -0,0 +1,133 @@
+ Status administration screen.
+ add_action( 'load-tools_page_action-scheduler', array( __CLASS__, 'register_admin_notice' ) );
+ add_action( 'load-woocommerce_page_wc-status', array( __CLASS__, 'register_admin_notice' ) );
+ }
+
+ /**
+ * Determines if there are log entries in the wp comments table.
+ *
+ * Uses the flag set on migration completion set by @see self::maybe_schedule_cleanup().
+ *
+ * @return boolean Whether there are scheduled action comments in the comments table.
+ */
+ public static function has_logs() {
+ return 'yes' === get_option( self::$has_logs_option_key );
+ }
+
+ /**
+ * Schedules the WP Post comment table cleanup to run in 6 months if it's not already scheduled.
+ * Attached to the migration complete hook 'action_scheduler/migration_complete'.
+ */
+ public static function maybe_schedule_cleanup() {
+ $has_logs = 'no';
+
+ $args = array(
+ 'type' => ActionScheduler_wpCommentLogger::TYPE,
+ 'number' => 1,
+ 'fields' => 'ids',
+ );
+
+ if ( (bool) get_comments( $args ) ) {
+ $has_logs = 'yes';
+
+ if ( ! as_next_scheduled_action( self::$cleanup_hook ) ) {
+ as_schedule_single_action( gmdate( 'U' ) + ( 6 * MONTH_IN_SECONDS ), self::$cleanup_hook );
+ }
+ }
+
+ update_option( self::$has_logs_option_key, $has_logs, true );
+ }
+
+ /**
+ * Delete all action comments from the WP Comments table.
+ */
+ public static function delete_all_action_comments() {
+ global $wpdb;
+
+ $wpdb->delete(
+ $wpdb->comments,
+ array(
+ 'comment_type' => ActionScheduler_wpCommentLogger::TYPE,
+ 'comment_agent' => ActionScheduler_wpCommentLogger::AGENT,
+ )
+ );
+
+ update_option( self::$has_logs_option_key, 'no', true );
+ }
+
+ /**
+ * Registers admin notices about the orphaned action logs.
+ */
+ public static function register_admin_notice() {
+ add_action( 'admin_notices', array( __CLASS__, 'print_admin_notice' ) );
+ }
+
+ /**
+ * Prints details about the orphaned action logs and includes information on where to learn more.
+ */
+ public static function print_admin_notice() {
+ $next_cleanup_message = '';
+ $next_scheduled_cleanup_hook = as_next_scheduled_action( self::$cleanup_hook );
+
+ if ( $next_scheduled_cleanup_hook ) {
+ /* translators: %s: date interval */
+ $next_cleanup_message = sprintf( __( 'This data will be deleted in %s.', 'action-scheduler' ), human_time_diff( gmdate( 'U' ), $next_scheduled_cleanup_hook ) );
+ }
+
+ $notice = sprintf(
+ /* translators: 1: next cleanup message 2: github issue URL */
+ __( 'Action Scheduler has migrated data to custom tables; however, orphaned log entries exist in the WordPress Comments table. %1$s Learn more »', 'action-scheduler' ),
+ $next_cleanup_message,
+ 'https://github.com/woocommerce/action-scheduler/issues/368'
+ );
+
+ echo '
' . wp_kses_post( $notice ) . '
';
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/ActionScheduler_wcSystemStatus.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/ActionScheduler_wcSystemStatus.php
new file mode 100755
index 00000000..cd6ca940
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/ActionScheduler_wcSystemStatus.php
@@ -0,0 +1,165 @@
+store = $store;
+ }
+
+ /**
+ * Display action data, including number of actions grouped by status and the oldest & newest action in each status.
+ *
+ * Helpful to identify issues, like a clogged queue.
+ */
+ public function render() {
+ $action_counts = $this->store->action_counts();
+ $status_labels = $this->store->get_status_labels();
+ $oldest_and_newest = $this->get_oldest_and_newest( array_keys( $status_labels ) );
+
+ $this->get_template( $status_labels, $action_counts, $oldest_and_newest );
+ }
+
+ /**
+ * Get oldest and newest scheduled dates for a given set of statuses.
+ *
+ * @param array $status_keys Set of statuses to find oldest & newest action for.
+ * @return array
+ */
+ protected function get_oldest_and_newest( $status_keys ) {
+
+ $oldest_and_newest = array();
+
+ foreach ( $status_keys as $status ) {
+ $oldest_and_newest[ $status ] = array(
+ 'oldest' => '–',
+ 'newest' => '–',
+ );
+
+ if ( 'in-progress' === $status ) {
+ continue;
+ }
+
+ $oldest_and_newest[ $status ]['oldest'] = $this->get_action_status_date( $status, 'oldest' );
+ $oldest_and_newest[ $status ]['newest'] = $this->get_action_status_date( $status, 'newest' );
+ }
+
+ return $oldest_and_newest;
+ }
+
+ /**
+ * Get oldest or newest scheduled date for a given status.
+ *
+ * @param string $status Action status label/name string.
+ * @param string $date_type Oldest or Newest.
+ * @return DateTime
+ */
+ protected function get_action_status_date( $status, $date_type = 'oldest' ) {
+
+ $order = 'oldest' === $date_type ? 'ASC' : 'DESC';
+
+ $action = $this->store->query_actions(
+ array(
+ 'status' => $status,
+ 'per_page' => 1,
+ 'order' => $order,
+ )
+ );
+
+ if ( ! empty( $action ) ) {
+ $date_object = $this->store->get_date( $action[0] );
+ $action_date = $date_object->format( 'Y-m-d H:i:s O' );
+ } else {
+ $action_date = '–';
+ }
+
+ return $action_date;
+ }
+
+ /**
+ * Get oldest or newest scheduled date for a given status.
+ *
+ * @param array $status_labels Set of statuses to find oldest & newest action for.
+ * @param array $action_counts Number of actions grouped by status.
+ * @param array $oldest_and_newest Date of the oldest and newest action with each status.
+ */
+ protected function get_template( $status_labels, $action_counts, $oldest_and_newest ) {
+ $as_version = ActionScheduler_Versions::instance()->latest_version();
+ $as_datastore = get_class( ActionScheduler_Store::instance() );
+ ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $count ) {
+ // WC uses the 3rd column for export, so we need to display more data in that (hidden when viewed as part of the table) and add an empty 2nd column.
+ printf(
+ '
';
+ }
+
+ /**
+ * Set the data for displaying. It will attempt to unserialize (There is a chance that some columns
+ * are serialized). This can be override in child classes for further data transformation.
+ *
+ * @param array $items Items array.
+ */
+ protected function set_items( array $items ) {
+ $this->items = array();
+ foreach ( $items as $item ) {
+ $this->items[ $item[ $this->ID ] ] = array_map( 'maybe_unserialize', $item );
+ }
+ }
+
+ /**
+ * Renders the checkbox for each row, this is the first column and it is named ID regardless
+ * of how the primary key is named (to keep the code simpler). The bulk actions will do the proper
+ * name transformation though using `$this->ID`.
+ *
+ * @param array $row The row to render.
+ */
+ public function column_cb( $row ) {
+ return '';
+ }
+
+ /**
+ * Renders the row-actions.
+ *
+ * This method renders the action menu, it reads the definition from the $row_actions property,
+ * and it checks that the row action method exists before rendering it.
+ *
+ * @param array $row Row to be rendered.
+ * @param string $column_name Column name.
+ * @return string
+ */
+ protected function maybe_render_actions( $row, $column_name ) {
+ if ( empty( $this->row_actions[ $column_name ] ) ) {
+ return;
+ }
+
+ $row_id = $row[ $this->ID ];
+
+ $actions = '
';
+ }
+ }
+
+ /**
+ * Renders the table list, we override the original class to render the table inside a form
+ * and to render any needed HTML (like the search box). By doing so the callee of a function can simple
+ * forget about any extra HTML.
+ */
+ protected function display_table() {
+ echo '';
+ }
+
+ /**
+ * Process any pending actions.
+ */
+ public function process_actions() {
+ $this->process_bulk_action();
+ $this->process_row_actions();
+
+ if ( ! empty( $_REQUEST['_wp_http_referer'] ) && ! empty( $_SERVER['REQUEST_URI'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+ // _wp_http_referer is used only on bulk actions, we remove it to keep the $_GET shorter
+ wp_safe_redirect( remove_query_arg( array( '_wp_http_referer', '_wpnonce' ), esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) ) );
+ exit;
+ }
+ }
+
+ /**
+ * Render the list table page, including header, notices, status filters and table.
+ */
+ public function display_page() {
+ $this->prepare_items();
+
+ echo '
';
+ }
+
+ /**
+ * Get the text to display in the search box on the list table.
+ */
+ protected function get_search_box_placeholder() {
+ return esc_html__( 'Search', 'action-scheduler' );
+ }
+
+ /**
+ * Gets the screen per_page option name.
+ *
+ * @return string
+ */
+ protected function get_per_page_option_name() {
+ return $this->package . '_items_per_page';
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Abstract_QueueRunner.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Abstract_QueueRunner.php
new file mode 100755
index 00000000..d5b4bf49
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Abstract_QueueRunner.php
@@ -0,0 +1,384 @@
+created_time = microtime( true );
+
+ $this->store = $store ? $store : ActionScheduler_Store::instance();
+ $this->monitor = $monitor ? $monitor : new ActionScheduler_FatalErrorMonitor( $this->store );
+ $this->cleaner = $cleaner ? $cleaner : new ActionScheduler_QueueCleaner( $this->store );
+ }
+
+ /**
+ * Process an individual action.
+ *
+ * @param int $action_id The action ID to process.
+ * @param string $context Optional identifier for the context in which this action is being processed, e.g. 'WP CLI' or 'WP Cron'
+ * Generally, this should be capitalised and not localised as it's a proper noun.
+ * @throws \Exception When error running action.
+ */
+ public function process_action( $action_id, $context = '' ) {
+ // Temporarily override the error handler while we process the current action.
+ // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_set_error_handler
+ set_error_handler(
+ /**
+ * Temporary error handler which can catch errors and convert them into exceptions. This facilitates more
+ * robust error handling across all supported PHP versions.
+ *
+ * @throws Exception
+ *
+ * @param int $type Error level expressed as an integer.
+ * @param string $message Error message.
+ */
+ function ( $type, $message ) {
+ throw new Exception( $message );
+ },
+ E_USER_ERROR | E_RECOVERABLE_ERROR
+ );
+
+ /*
+ * The nested try/catch structure is required because we potentially need to convert thrown errors into
+ * exceptions (and an exception thrown from a catch block cannot be caught by a later catch block in the *same*
+ * structure).
+ */
+ try {
+ try {
+ $valid_action = true;
+
+ do_action( 'action_scheduler_before_execute', $action_id, $context );
+
+ if ( ActionScheduler_Store::STATUS_PENDING !== $this->store->get_status( $action_id ) ) {
+ $valid_action = false;
+ do_action( 'action_scheduler_execution_ignored', $action_id, $context );
+ return;
+ }
+
+ do_action( 'action_scheduler_begin_execute', $action_id, $context );
+
+ $action = $this->store->fetch_action( $action_id );
+ $this->store->log_execution( $action_id );
+ $action->execute();
+ do_action( 'action_scheduler_after_execute', $action_id, $action, $context );
+ $this->store->mark_complete( $action_id );
+ } catch ( Throwable $e ) {
+ // Throwable is defined when executing under PHP 7.0 and up. We convert it to an exception, for
+ // compatibility with ActionScheduler_Logger.
+ throw new Exception( $e->getMessage(), $e->getCode(), $e );
+ }
+ } catch ( Exception $e ) {
+ // This catch block exists for compatibility with PHP 5.6.
+ $this->handle_action_error( $action_id, $e, $context, $valid_action );
+ } finally {
+ restore_error_handler();
+ }
+
+ if ( isset( $action ) && is_a( $action, 'ActionScheduler_Action' ) && $action->get_schedule()->is_recurring() ) {
+ $this->schedule_next_instance( $action, $action_id );
+ }
+ }
+
+ /**
+ * Marks actions as either having failed execution or failed validation, as appropriate.
+ *
+ * @param int $action_id Action ID.
+ * @param Exception $e Exception instance.
+ * @param string $context Execution context.
+ * @param bool $valid_action If the action is valid.
+ *
+ * @return void
+ */
+ private function handle_action_error( $action_id, $e, $context, $valid_action ) {
+ if ( $valid_action ) {
+ $this->store->mark_failure( $action_id );
+ /**
+ * Runs when action execution fails.
+ *
+ * @param int $action_id Action ID.
+ * @param Exception $e Exception instance.
+ * @param string $context Execution context.
+ */
+ do_action( 'action_scheduler_failed_execution', $action_id, $e, $context );
+ } else {
+ /**
+ * Runs when action validation fails.
+ *
+ * @param int $action_id Action ID.
+ * @param Exception $e Exception instance.
+ * @param string $context Execution context.
+ */
+ do_action( 'action_scheduler_failed_validation', $action_id, $e, $context );
+ }
+ }
+
+ /**
+ * Schedule the next instance of the action if necessary.
+ *
+ * @param ActionScheduler_Action $action Action.
+ * @param int $action_id Action ID.
+ */
+ protected function schedule_next_instance( ActionScheduler_Action $action, $action_id ) {
+ // If a recurring action has been consistently failing, we may wish to stop rescheduling it.
+ if (
+ ActionScheduler_Store::STATUS_FAILED === $this->store->get_status( $action_id )
+ && $this->recurring_action_is_consistently_failing( $action, $action_id )
+ ) {
+ ActionScheduler_Logger::instance()->log(
+ $action_id,
+ __( 'This action appears to be consistently failing. A new instance will not be scheduled.', 'action-scheduler' )
+ );
+
+ return;
+ }
+
+ try {
+ ActionScheduler::factory()->repeat( $action );
+ } catch ( Exception $e ) {
+ do_action( 'action_scheduler_failed_to_schedule_next_instance', $action_id, $e, $action );
+ }
+ }
+
+ /**
+ * Determine if the specified recurring action has been consistently failing.
+ *
+ * @param ActionScheduler_Action $action The recurring action to be rescheduled.
+ * @param int $action_id The ID of the recurring action.
+ *
+ * @return bool
+ */
+ private function recurring_action_is_consistently_failing( ActionScheduler_Action $action, $action_id ) {
+ /**
+ * Controls the failure threshold for recurring actions.
+ *
+ * Before rescheduling a recurring action, we look at its status. If it failed, we then check if all of the most
+ * recent actions (upto the threshold set by this filter) sharing the same hook have also failed: if they have,
+ * that is considered consistent failure and a new instance of the action will not be scheduled.
+ *
+ * @param int $failure_threshold Number of actions of the same hook to examine for failure. Defaults to 5.
+ */
+ $consistent_failure_threshold = (int) apply_filters( 'action_scheduler_recurring_action_failure_threshold', 5 );
+
+ // This query should find the earliest *failing* action (for the hook we are interested in) within our threshold.
+ $query_args = array(
+ 'hook' => $action->get_hook(),
+ 'status' => ActionScheduler_Store::STATUS_FAILED,
+ 'date' => date_create( 'now', timezone_open( 'UTC' ) )->format( 'Y-m-d H:i:s' ),
+ 'date_compare' => '<',
+ 'per_page' => 1,
+ 'offset' => $consistent_failure_threshold - 1,
+ );
+
+ $first_failing_action_id = $this->store->query_actions( $query_args );
+
+ // If we didn't retrieve an action ID, then there haven't been enough failures for us to worry about.
+ if ( empty( $first_failing_action_id ) ) {
+ return false;
+ }
+
+ // Now let's fetch the first action (having the same hook) of *any status* within the same window.
+ unset( $query_args['status'] );
+ $first_action_id_with_the_same_hook = $this->store->query_actions( $query_args );
+
+ /**
+ * If a recurring action is assessed as consistently failing, it will not be rescheduled. This hook provides a
+ * way to observe and optionally override that assessment.
+ *
+ * @param bool $is_consistently_failing If the action is considered to be consistently failing.
+ * @param ActionScheduler_Action $action The action being assessed.
+ */
+ return (bool) apply_filters(
+ 'action_scheduler_recurring_action_is_consistently_failing',
+ $first_action_id_with_the_same_hook === $first_failing_action_id,
+ $action
+ );
+ }
+
+ /**
+ * Run the queue cleaner.
+ */
+ protected function run_cleanup() {
+ $this->cleaner->clean( 10 * $this->get_time_limit() );
+ }
+
+ /**
+ * Get the number of concurrent batches a runner allows.
+ *
+ * @return int
+ */
+ public function get_allowed_concurrent_batches() {
+ return apply_filters( 'action_scheduler_queue_runner_concurrent_batches', 1 );
+ }
+
+ /**
+ * Check if the number of allowed concurrent batches is met or exceeded.
+ *
+ * @return bool
+ */
+ public function has_maximum_concurrent_batches() {
+ return $this->store->get_claim_count() >= $this->get_allowed_concurrent_batches();
+ }
+
+ /**
+ * Get the maximum number of seconds a batch can run for.
+ *
+ * @return int The number of seconds.
+ */
+ protected function get_time_limit() {
+
+ $time_limit = 30;
+
+ // Apply deprecated filter from deprecated get_maximum_execution_time() method.
+ if ( has_filter( 'action_scheduler_maximum_execution_time' ) ) {
+ _deprecated_function( 'action_scheduler_maximum_execution_time', '2.1.1', 'action_scheduler_queue_runner_time_limit' );
+ $time_limit = apply_filters( 'action_scheduler_maximum_execution_time', $time_limit );
+ }
+
+ return absint( apply_filters( 'action_scheduler_queue_runner_time_limit', $time_limit ) );
+ }
+
+ /**
+ * Get the number of seconds the process has been running.
+ *
+ * @return int The number of seconds.
+ */
+ protected function get_execution_time() {
+ $execution_time = microtime( true ) - $this->created_time;
+
+ // Get the CPU time if the hosting environment uses it rather than wall-clock time to calculate a process's execution time.
+ if ( function_exists( 'getrusage' ) && apply_filters( 'action_scheduler_use_cpu_execution_time', defined( 'PANTHEON_ENVIRONMENT' ) ) ) {
+ $resource_usages = getrusage();
+
+ if ( isset( $resource_usages['ru_stime.tv_usec'], $resource_usages['ru_stime.tv_usec'] ) ) {
+ $execution_time = $resource_usages['ru_stime.tv_sec'] + ( $resource_usages['ru_stime.tv_usec'] / 1000000 );
+ }
+ }
+
+ return $execution_time;
+ }
+
+ /**
+ * Check if the host's max execution time is (likely) to be exceeded if processing more actions.
+ *
+ * @param int $processed_actions The number of actions processed so far - used to determine the likelihood of exceeding the time limit if processing another action.
+ * @return bool
+ */
+ protected function time_likely_to_be_exceeded( $processed_actions ) {
+ $execution_time = $this->get_execution_time();
+ $max_execution_time = $this->get_time_limit();
+
+ // Safety against division by zero errors.
+ if ( 0 === $processed_actions ) {
+ return $execution_time >= $max_execution_time;
+ }
+
+ $time_per_action = $execution_time / $processed_actions;
+ $estimated_time = $execution_time + ( $time_per_action * 3 );
+ $likely_to_be_exceeded = $estimated_time > $max_execution_time;
+
+ return apply_filters( 'action_scheduler_maximum_execution_time_likely_to_be_exceeded', $likely_to_be_exceeded, $this, $processed_actions, $execution_time, $max_execution_time );
+ }
+
+ /**
+ * Get memory limit
+ *
+ * Based on WP_Background_Process::get_memory_limit()
+ *
+ * @return int
+ */
+ protected function get_memory_limit() {
+ if ( function_exists( 'ini_get' ) ) {
+ $memory_limit = ini_get( 'memory_limit' );
+ } else {
+ $memory_limit = '128M'; // Sensible default, and minimum required by WooCommerce.
+ }
+
+ if ( ! $memory_limit || -1 === $memory_limit || '-1' === $memory_limit ) {
+ // Unlimited, set to 32GB.
+ $memory_limit = '32G';
+ }
+
+ return ActionScheduler_Compatibility::convert_hr_to_bytes( $memory_limit );
+ }
+
+ /**
+ * Memory exceeded
+ *
+ * Ensures the batch process never exceeds 90% of the maximum WordPress memory.
+ *
+ * Based on WP_Background_Process::memory_exceeded()
+ *
+ * @return bool
+ */
+ protected function memory_exceeded() {
+
+ $memory_limit = $this->get_memory_limit() * 0.90;
+ $current_memory = memory_get_usage( true );
+ $memory_exceeded = $current_memory >= $memory_limit;
+
+ return apply_filters( 'action_scheduler_memory_exceeded', $memory_exceeded, $this );
+ }
+
+ /**
+ * See if the batch limits have been exceeded, which is when memory usage is almost at
+ * the maximum limit, or the time to process more actions will exceed the max time limit.
+ *
+ * Based on WC_Background_Process::batch_limits_exceeded()
+ *
+ * @param int $processed_actions The number of actions processed so far - used to determine the likelihood of exceeding the time limit if processing another action.
+ * @return bool
+ */
+ protected function batch_limits_exceeded( $processed_actions ) {
+ return $this->memory_exceeded() || $this->time_likely_to_be_exceeded( $processed_actions );
+ }
+
+ /**
+ * Process actions in the queue.
+ *
+ * @param string $context Optional identifier for the context in which this action is being processed, e.g. 'WP CLI' or 'WP Cron'
+ * Generally, this should be capitalised and not localised as it's a proper noun.
+ * @return int The number of actions processed.
+ */
+ abstract public function run( $context = '' );
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Abstract_RecurringSchedule.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Abstract_RecurringSchedule.php
new file mode 100755
index 00000000..60d09e91
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Abstract_RecurringSchedule.php
@@ -0,0 +1,112 @@
+start - and logic to calculate the next run date after
+ * that - @see $this->calculate_next(). The $first_date property also keeps a record of when the very
+ * first instance of this chain of schedules ran.
+ *
+ * @var DateTime
+ */
+ private $first_date = null;
+
+ /**
+ * Timestamp equivalent of @see $this->first_date
+ *
+ * @var int
+ */
+ protected $first_timestamp = null;
+
+ /**
+ * The recurrence between each time an action is run using this schedule.
+ * Used to calculate the start date & time. Can be a number of seconds, in the
+ * case of ActionScheduler_IntervalSchedule, or a cron expression, as in the
+ * case of ActionScheduler_CronSchedule. Or something else.
+ *
+ * @var mixed
+ */
+ protected $recurrence;
+
+ /**
+ * Construct.
+ *
+ * @param DateTime $date The date & time to run the action.
+ * @param mixed $recurrence The data used to determine the schedule's recurrence.
+ * @param DateTime|null $first (Optional) The date & time the first instance of this interval schedule ran. Default null, meaning this is the first instance.
+ */
+ public function __construct( DateTime $date, $recurrence, ?DateTime $first = null ) {
+ parent::__construct( $date );
+ $this->first_date = empty( $first ) ? $date : $first;
+ $this->recurrence = $recurrence;
+ }
+
+ /**
+ * Schedule is recurring.
+ *
+ * @return bool
+ */
+ public function is_recurring() {
+ return true;
+ }
+
+ /**
+ * Get the date & time of the first schedule in this recurring series.
+ *
+ * @return DateTime|null
+ */
+ public function get_first_date() {
+ return clone $this->first_date;
+ }
+
+ /**
+ * Get the schedule's recurrence.
+ *
+ * @return string
+ */
+ public function get_recurrence() {
+ return $this->recurrence;
+ }
+
+ /**
+ * For PHP 5.2 compat, since DateTime objects can't be serialized
+ *
+ * @return array
+ */
+ public function __sleep() {
+ $sleep_params = parent::__sleep();
+ $this->first_timestamp = $this->first_date->getTimestamp();
+ return array_merge(
+ $sleep_params,
+ array(
+ 'first_timestamp',
+ 'recurrence',
+ )
+ );
+ }
+
+ /**
+ * Unserialize recurring schedules serialized/stored prior to AS 3.0.0
+ *
+ * Prior to Action Scheduler 3.0.0, schedules used different property names to refer
+ * to equivalent data. For example, ActionScheduler_IntervalSchedule::start_timestamp
+ * was the same as ActionScheduler_SimpleSchedule::timestamp. This was addressed in
+ * Action Scheduler 3.0.0, where properties and property names were aligned for better
+ * inheritance. To maintain backward compatibility with scheduled serialized and stored
+ * prior to 3.0, we need to correctly map the old property names.
+ */
+ public function __wakeup() {
+ parent::__wakeup();
+ if ( $this->first_timestamp > 0 ) {
+ $this->first_date = as_get_datetime_object( $this->first_timestamp );
+ } else {
+ $this->first_date = $this->get_date();
+ }
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Abstract_Schedule.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Abstract_Schedule.php
new file mode 100755
index 00000000..b7826b41
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Abstract_Schedule.php
@@ -0,0 +1,89 @@
+scheduled_date
+ *
+ * @var int
+ */
+ protected $scheduled_timestamp = null;
+
+ /**
+ * Construct.
+ *
+ * @param DateTime $date The date & time to run the action.
+ */
+ public function __construct( DateTime $date ) {
+ $this->scheduled_date = $date;
+ }
+
+ /**
+ * Check if a schedule should recur.
+ *
+ * @return bool
+ */
+ abstract public function is_recurring();
+
+ /**
+ * Calculate when the next instance of this schedule would run based on a given date & time.
+ *
+ * @param DateTime $after Start timestamp.
+ * @return DateTime
+ */
+ abstract protected function calculate_next( DateTime $after );
+
+ /**
+ * Get the next date & time when this schedule should run after a given date & time.
+ *
+ * @param DateTime $after Start timestamp.
+ * @return DateTime|null
+ */
+ public function get_next( DateTime $after ) {
+ $after = clone $after;
+ if ( $after > $this->scheduled_date ) {
+ $after = $this->calculate_next( $after );
+ return $after;
+ }
+ return clone $this->scheduled_date;
+ }
+
+ /**
+ * Get the date & time the schedule is set to run.
+ *
+ * @return DateTime|null
+ */
+ public function get_date() {
+ return $this->scheduled_date;
+ }
+
+ /**
+ * For PHP 5.2 compat, because DateTime objects can't be serialized
+ *
+ * @return array
+ */
+ public function __sleep() {
+ $this->scheduled_timestamp = $this->scheduled_date->getTimestamp();
+ return array(
+ 'scheduled_timestamp',
+ );
+ }
+
+ /**
+ * Wakeup.
+ */
+ public function __wakeup() {
+ $this->scheduled_date = as_get_datetime_object( $this->scheduled_timestamp );
+ unset( $this->scheduled_timestamp );
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Abstract_Schema.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Abstract_Schema.php
new file mode 100755
index 00000000..69817fe7
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Abstract_Schema.php
@@ -0,0 +1,187 @@
+tables as $table ) {
+ $wpdb->tables[] = $table;
+ $name = $this->get_full_table_name( $table );
+ $wpdb->$table = $name;
+ }
+
+ // create the tables.
+ if ( $this->schema_update_required() || $force_update ) {
+ foreach ( $this->tables as $table ) {
+ /**
+ * Allow custom processing before updating a table schema.
+ *
+ * @param string $table Name of table being updated.
+ * @param string $db_version Existing version of the table being updated.
+ */
+ do_action( 'action_scheduler_before_schema_update', $table, $this->db_version );
+ $this->update_table( $table );
+ }
+ $this->mark_schema_update_complete();
+ }
+ }
+
+ /**
+ * Get table definition.
+ *
+ * @param string $table The name of the table.
+ *
+ * @return string The CREATE TABLE statement, suitable for passing to dbDelta
+ */
+ abstract protected function get_table_definition( $table );
+
+ /**
+ * Determine if the database schema is out of date
+ * by comparing the integer found in $this->schema_version
+ * with the option set in the WordPress options table
+ *
+ * @return bool
+ */
+ private function schema_update_required() {
+ $option_name = 'schema-' . static::class;
+ $this->db_version = get_option( $option_name, 0 );
+
+ // Check for schema option stored by the Action Scheduler Custom Tables plugin in case site has migrated from that plugin with an older schema.
+ if ( 0 === $this->db_version ) {
+
+ $plugin_option_name = 'schema-';
+
+ switch ( static::class ) {
+ case 'ActionScheduler_StoreSchema':
+ $plugin_option_name .= 'Action_Scheduler\Custom_Tables\DB_Store_Table_Maker';
+ break;
+ case 'ActionScheduler_LoggerSchema':
+ $plugin_option_name .= 'Action_Scheduler\Custom_Tables\DB_Logger_Table_Maker';
+ break;
+ }
+
+ $this->db_version = get_option( $plugin_option_name, 0 );
+
+ delete_option( $plugin_option_name );
+ }
+
+ return version_compare( $this->db_version, $this->schema_version, '<' );
+ }
+
+ /**
+ * Update the option in WordPress to indicate that
+ * our schema is now up to date
+ *
+ * @return void
+ */
+ private function mark_schema_update_complete() {
+ $option_name = 'schema-' . static::class;
+
+ // work around race conditions and ensure that our option updates.
+ $value_to_save = (string) $this->schema_version . '.0.' . time();
+
+ update_option( $option_name, $value_to_save );
+ }
+
+ /**
+ * Update the schema for the given table
+ *
+ * @param string $table The name of the table to update.
+ *
+ * @return void
+ */
+ private function update_table( $table ) {
+ require_once ABSPATH . 'wp-admin/includes/upgrade.php';
+ $definition = $this->get_table_definition( $table );
+ if ( $definition ) {
+ $updated = dbDelta( $definition );
+ foreach ( $updated as $updated_table => $update_description ) {
+ if ( strpos( $update_description, 'Created table' ) === 0 ) {
+ do_action( 'action_scheduler/created_table', $updated_table, $table ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
+ }
+ }
+ }
+ }
+
+ /**
+ * Get full table name.
+ *
+ * @param string $table Table name.
+ *
+ * @return string The full name of the table, including the
+ * table prefix for the current blog
+ */
+ protected function get_full_table_name( $table ) {
+ return $GLOBALS['wpdb']->prefix . $table;
+ }
+
+ /**
+ * Confirms that all of the tables registered by this schema class have been created.
+ *
+ * @return bool
+ */
+ public function tables_exist() {
+ global $wpdb;
+
+ $tables_exist = true;
+
+ foreach ( $this->tables as $table_name ) {
+ $table_name = $wpdb->prefix . $table_name;
+ $pattern = str_replace( '_', '\\_', $table_name );
+ $existing_table = $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $pattern ) );
+
+ if ( $existing_table !== $table_name ) {
+ $tables_exist = false;
+ break;
+ }
+ }
+
+ return $tables_exist;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Lock.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Lock.php
new file mode 100755
index 00000000..72802077
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Lock.php
@@ -0,0 +1,74 @@
+get_expiration( $lock_type ) >= time() );
+ }
+
+ /**
+ * Set a lock.
+ *
+ * To prevent race conditions, implementations should avoid setting the lock if the lock is already held.
+ *
+ * @param string $lock_type A string to identify different lock types.
+ * @return bool
+ */
+ abstract public function set( $lock_type );
+
+ /**
+ * If a lock is set, return the timestamp it was set to expiry.
+ *
+ * @param string $lock_type A string to identify different lock types.
+ * @return bool|int False if no lock is set, otherwise the timestamp for when the lock is set to expire.
+ */
+ abstract public function get_expiration( $lock_type );
+
+ /**
+ * Get the amount of time to set for a given lock. 60 seconds by default.
+ *
+ * @param string $lock_type A string to identify different lock types.
+ * @return int
+ */
+ protected function get_duration( $lock_type ) {
+ return apply_filters( 'action_scheduler_lock_duration', self::$lock_duration, $lock_type );
+ }
+
+ /**
+ * Get instance.
+ *
+ * @return ActionScheduler_Lock
+ */
+ public static function instance() {
+ if ( empty( self::$locker ) ) {
+ $class = apply_filters( 'action_scheduler_lock_class', 'ActionScheduler_OptionLock' );
+ self::$locker = new $class();
+ }
+ return self::$locker;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Logger.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Logger.php
new file mode 100755
index 00000000..94ee2a93
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Logger.php
@@ -0,0 +1,258 @@
+hook_stored_action();
+ add_action( 'action_scheduler_canceled_action', array( $this, 'log_canceled_action' ), 10, 1 );
+ add_action( 'action_scheduler_begin_execute', array( $this, 'log_started_action' ), 10, 2 );
+ add_action( 'action_scheduler_after_execute', array( $this, 'log_completed_action' ), 10, 3 );
+ add_action( 'action_scheduler_failed_execution', array( $this, 'log_failed_action' ), 10, 3 );
+ add_action( 'action_scheduler_failed_action', array( $this, 'log_timed_out_action' ), 10, 2 );
+ add_action( 'action_scheduler_unexpected_shutdown', array( $this, 'log_unexpected_shutdown' ), 10, 2 );
+ add_action( 'action_scheduler_reset_action', array( $this, 'log_reset_action' ), 10, 1 );
+ add_action( 'action_scheduler_execution_ignored', array( $this, 'log_ignored_action' ), 10, 2 );
+ add_action( 'action_scheduler_failed_fetch_action', array( $this, 'log_failed_fetch_action' ), 10, 2 );
+ add_action( 'action_scheduler_failed_to_schedule_next_instance', array( $this, 'log_failed_schedule_next_instance' ), 10, 2 );
+ add_action( 'action_scheduler_bulk_cancel_actions', array( $this, 'bulk_log_cancel_actions' ), 10, 1 );
+ }
+
+ /**
+ * Register callback for storing action.
+ */
+ public function hook_stored_action() {
+ add_action( 'action_scheduler_stored_action', array( $this, 'log_stored_action' ) );
+ }
+
+ /**
+ * Unhook callback for storing action.
+ */
+ public function unhook_stored_action() {
+ remove_action( 'action_scheduler_stored_action', array( $this, 'log_stored_action' ) );
+ }
+
+ /**
+ * Log action stored.
+ *
+ * @param int $action_id Action ID.
+ */
+ public function log_stored_action( $action_id ) {
+ $this->log( $action_id, __( 'action created', 'action-scheduler' ) );
+ }
+
+ /**
+ * Log action cancellation.
+ *
+ * @param int $action_id Action ID.
+ */
+ public function log_canceled_action( $action_id ) {
+ $this->log( $action_id, __( 'action canceled', 'action-scheduler' ) );
+ }
+
+ /**
+ * Log action start.
+ *
+ * @param int $action_id Action ID.
+ * @param string $context Action execution context.
+ */
+ public function log_started_action( $action_id, $context = '' ) {
+ if ( ! empty( $context ) ) {
+ /* translators: %s: context */
+ $message = sprintf( __( 'action started via %s', 'action-scheduler' ), $context );
+ } else {
+ $message = __( 'action started', 'action-scheduler' );
+ }
+ $this->log( $action_id, $message );
+ }
+
+ /**
+ * Log action completion.
+ *
+ * @param int $action_id Action ID.
+ * @param null|ActionScheduler_Action $action Action.
+ * @param string $context Action execution context.
+ */
+ public function log_completed_action( $action_id, $action = null, $context = '' ) {
+ if ( ! empty( $context ) ) {
+ /* translators: %s: context */
+ $message = sprintf( __( 'action complete via %s', 'action-scheduler' ), $context );
+ } else {
+ $message = __( 'action complete', 'action-scheduler' );
+ }
+ $this->log( $action_id, $message );
+ }
+
+ /**
+ * Log action failure.
+ *
+ * @param int $action_id Action ID.
+ * @param Exception $exception Exception.
+ * @param string $context Action execution context.
+ */
+ public function log_failed_action( $action_id, Exception $exception, $context = '' ) {
+ if ( ! empty( $context ) ) {
+ /* translators: 1: context 2: exception message */
+ $message = sprintf( __( 'action failed via %1$s: %2$s', 'action-scheduler' ), $context, $exception->getMessage() );
+ } else {
+ /* translators: %s: exception message */
+ $message = sprintf( __( 'action failed: %s', 'action-scheduler' ), $exception->getMessage() );
+ }
+ $this->log( $action_id, $message );
+ }
+
+ /**
+ * Log action timeout.
+ *
+ * @param int $action_id Action ID.
+ * @param string $timeout Timeout.
+ */
+ public function log_timed_out_action( $action_id, $timeout ) {
+ /* translators: %s: amount of time */
+ $this->log( $action_id, sprintf( __( 'action marked as failed after %s seconds. Unknown error occurred. Check server, PHP and database error logs to diagnose cause.', 'action-scheduler' ), $timeout ) );
+ }
+
+ /**
+ * Log unexpected shutdown.
+ *
+ * @param int $action_id Action ID.
+ * @param mixed[] $error Error.
+ */
+ public function log_unexpected_shutdown( $action_id, $error ) {
+ if ( ! empty( $error ) ) {
+ /* translators: 1: error message 2: filename 3: line */
+ $this->log( $action_id, sprintf( __( 'unexpected shutdown: PHP Fatal error %1$s in %2$s on line %3$s', 'action-scheduler' ), $error['message'], $error['file'], $error['line'] ) );
+ }
+ }
+
+ /**
+ * Log action reset.
+ *
+ * @param int $action_id Action ID.
+ */
+ public function log_reset_action( $action_id ) {
+ $this->log( $action_id, __( 'action reset', 'action-scheduler' ) );
+ }
+
+ /**
+ * Log ignored action.
+ *
+ * @param int $action_id Action ID.
+ * @param string $context Action execution context.
+ */
+ public function log_ignored_action( $action_id, $context = '' ) {
+ if ( ! empty( $context ) ) {
+ /* translators: %s: context */
+ $message = sprintf( __( 'action ignored via %s', 'action-scheduler' ), $context );
+ } else {
+ $message = __( 'action ignored', 'action-scheduler' );
+ }
+ $this->log( $action_id, $message );
+ }
+
+ /**
+ * Log the failure of fetching the action.
+ *
+ * @param string $action_id Action ID.
+ * @param null|Exception $exception The exception which occurred when fetching the action. NULL by default for backward compatibility.
+ */
+ public function log_failed_fetch_action( $action_id, ?Exception $exception = null ) {
+
+ if ( ! is_null( $exception ) ) {
+ /* translators: %s: exception message */
+ $log_message = sprintf( __( 'There was a failure fetching this action: %s', 'action-scheduler' ), $exception->getMessage() );
+ } else {
+ $log_message = __( 'There was a failure fetching this action', 'action-scheduler' );
+ }
+
+ $this->log( $action_id, $log_message );
+ }
+
+ /**
+ * Log the failure of scheduling the action's next instance.
+ *
+ * @param int $action_id Action ID.
+ * @param Exception $exception Exception object.
+ */
+ public function log_failed_schedule_next_instance( $action_id, Exception $exception ) {
+ /* translators: %s: exception message */
+ $this->log( $action_id, sprintf( __( 'There was a failure scheduling the next instance of this action: %s', 'action-scheduler' ), $exception->getMessage() ) );
+ }
+
+ /**
+ * Bulk add cancel action log entries.
+ *
+ * Implemented here for backward compatibility. Should be implemented in parent loggers
+ * for more performant bulk logging.
+ *
+ * @param array $action_ids List of action ID.
+ */
+ public function bulk_log_cancel_actions( $action_ids ) {
+ if ( empty( $action_ids ) ) {
+ return;
+ }
+
+ foreach ( $action_ids as $action_id ) {
+ $this->log_canceled_action( $action_id );
+ }
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Store.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Store.php
new file mode 100755
index 00000000..bf6bc429
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Store.php
@@ -0,0 +1,506 @@
+ null,
+ 'status' => self::STATUS_PENDING,
+ 'group' => '',
+ )
+ );
+
+ // These params are fixed for this method.
+ $params['hook'] = $hook;
+ $params['orderby'] = 'date';
+ $params['per_page'] = 1;
+
+ if ( ! empty( $params['status'] ) ) {
+ if ( self::STATUS_PENDING === $params['status'] ) {
+ $params['order'] = 'ASC'; // Find the next action that matches.
+ } else {
+ $params['order'] = 'DESC'; // Find the most recent action that matches.
+ }
+ }
+
+ $results = $this->query_actions( $params );
+
+ return empty( $results ) ? null : $results[0];
+ }
+
+ /**
+ * Query for action count or list of action IDs.
+ *
+ * @since 3.3.0 $query['status'] accepts array of statuses instead of a single status.
+ *
+ * @param array $query {
+ * Query filtering options.
+ *
+ * @type string $hook The name of the actions. Optional.
+ * @type string|array $status The status or statuses of the actions. Optional.
+ * @type array $args The args array of the actions. Optional.
+ * @type DateTime $date The scheduled date of the action. Used in UTC timezone. Optional.
+ * @type string $date_compare Operator for selecting by $date param. Accepted values are '!=', '>', '>=', '<', '<=', '='. Defaults to '<='.
+ * @type DateTime $modified The last modified date of the action. Used in UTC timezone. Optional.
+ * @type string $modified_compare Operator for comparing $modified param. Accepted values are '!=', '>', '>=', '<', '<=', '='. Defaults to '<='.
+ * @type string $group The group the action belongs to. Optional.
+ * @type bool|int $claimed TRUE to find claimed actions, FALSE to find unclaimed actions, an int to find a specific claim ID. Optional.
+ * @type int $per_page Number of results to return. Defaults to 5.
+ * @type int $offset The query pagination offset. Defaults to 0.
+ * @type int $orderby Accepted values are 'hook', 'group', 'modified', 'date' or 'none'. Defaults to 'date'.
+ * @type string $order Accepted values are 'ASC' or 'DESC'. Defaults to 'ASC'.
+ * }
+ * @param string $query_type Whether to select or count the results. Default, select.
+ *
+ * @return string|array|null The IDs of actions matching the query. Null on failure.
+ */
+ abstract public function query_actions( $query = array(), $query_type = 'select' );
+
+ /**
+ * Run query to get a single action ID.
+ *
+ * @since 3.3.0
+ *
+ * @see ActionScheduler_Store::query_actions for $query arg usage but 'per_page' and 'offset' can't be used.
+ *
+ * @param array $query Query parameters.
+ *
+ * @return int|null
+ */
+ public function query_action( $query ) {
+ $query['per_page'] = 1;
+ $query['offset'] = 0;
+ $results = $this->query_actions( $query );
+
+ if ( empty( $results ) ) {
+ return null;
+ } else {
+ return (int) $results[0];
+ }
+ }
+
+ /**
+ * Get a count of all actions in the store, grouped by status
+ *
+ * @return array
+ */
+ abstract public function action_counts();
+
+ /**
+ * Get additional action counts.
+ *
+ * - add past-due actions
+ *
+ * @return array
+ */
+ public function extra_action_counts() {
+ $extra_actions = array();
+
+ $pastdue_action_counts = (int) $this->query_actions(
+ array(
+ 'status' => self::STATUS_PENDING,
+ 'date' => as_get_datetime_object(),
+ ),
+ 'count'
+ );
+
+ if ( $pastdue_action_counts ) {
+ $extra_actions['past-due'] = $pastdue_action_counts;
+ }
+
+ /**
+ * Allows 3rd party code to add extra action counts (used in filters in the list table).
+ *
+ * @since 3.5.0
+ * @param $extra_actions array Array with format action_count_identifier => action count.
+ */
+ return apply_filters( 'action_scheduler_extra_action_counts', $extra_actions );
+ }
+
+ /**
+ * Cancel action.
+ *
+ * @param string $action_id Action ID.
+ */
+ abstract public function cancel_action( $action_id );
+
+ /**
+ * Delete action.
+ *
+ * @param string $action_id Action ID.
+ */
+ abstract public function delete_action( $action_id );
+
+ /**
+ * Get action's schedule or run timestamp.
+ *
+ * @param string $action_id Action ID.
+ *
+ * @return DateTime The date the action is schedule to run, or the date that it ran.
+ */
+ abstract public function get_date( $action_id );
+
+
+ /**
+ * Make a claim.
+ *
+ * @param int $max_actions Maximum number of actions to claim.
+ * @param DateTime|null $before_date Claim only actions schedule before the given date. Defaults to now.
+ * @param array $hooks Claim only actions with a hook or hooks.
+ * @param string $group Claim only actions in the given group.
+ *
+ * @return ActionScheduler_ActionClaim
+ */
+ abstract public function stake_claim( $max_actions = 10, ?DateTime $before_date = null, $hooks = array(), $group = '' );
+
+ /**
+ * Get claim count.
+ *
+ * @return int
+ */
+ abstract public function get_claim_count();
+
+ /**
+ * Release the claim.
+ *
+ * @param ActionScheduler_ActionClaim $claim Claim object.
+ */
+ abstract public function release_claim( ActionScheduler_ActionClaim $claim );
+
+ /**
+ * Un-claim the action.
+ *
+ * @param string $action_id Action ID.
+ */
+ abstract public function unclaim_action( $action_id );
+
+ /**
+ * Mark action as failed.
+ *
+ * @param string $action_id Action ID.
+ */
+ abstract public function mark_failure( $action_id );
+
+ /**
+ * Log action's execution.
+ *
+ * @param string $action_id Actoin ID.
+ */
+ abstract public function log_execution( $action_id );
+
+ /**
+ * Mark action as complete.
+ *
+ * @param string $action_id Action ID.
+ */
+ abstract public function mark_complete( $action_id );
+
+ /**
+ * Get action's status.
+ *
+ * @param string $action_id Action ID.
+ * @return string
+ */
+ abstract public function get_status( $action_id );
+
+ /**
+ * Get action's claim ID.
+ *
+ * @param string $action_id Action ID.
+ * @return mixed
+ */
+ abstract public function get_claim_id( $action_id );
+
+ /**
+ * Find actions by claim ID.
+ *
+ * @param string $claim_id Claim ID.
+ * @return array
+ */
+ abstract public function find_actions_by_claim_id( $claim_id );
+
+ /**
+ * Validate SQL operator.
+ *
+ * @param string $comparison_operator Operator.
+ * @return string
+ */
+ protected function validate_sql_comparator( $comparison_operator ) {
+ if ( in_array( $comparison_operator, array( '!=', '>', '>=', '<', '<=', '=' ), true ) ) {
+ return $comparison_operator;
+ }
+
+ return '=';
+ }
+
+ /**
+ * Get the time MySQL formatted date/time string for an action's (next) scheduled date.
+ *
+ * @param ActionScheduler_Action $action Action.
+ * @param null|DateTime $scheduled_date Action's schedule date (optional).
+ * @return string
+ */
+ protected function get_scheduled_date_string( ActionScheduler_Action $action, ?DateTime $scheduled_date = null ) {
+ $next = is_null( $scheduled_date ) ? $action->get_schedule()->get_date() : $scheduled_date;
+
+ if ( ! $next ) {
+ $next = date_create();
+ }
+
+ $next->setTimezone( new DateTimeZone( 'UTC' ) );
+
+ return $next->format( 'Y-m-d H:i:s' );
+ }
+
+ /**
+ * Get the time MySQL formatted date/time string for an action's (next) scheduled date.
+ *
+ * @param ActionScheduler_Action|null $action Action.
+ * @param null|DateTime $scheduled_date Action's scheduled date (optional).
+ * @return string
+ */
+ protected function get_scheduled_date_string_local( ActionScheduler_Action $action, ?DateTime $scheduled_date = null ) {
+ $next = is_null( $scheduled_date ) ? $action->get_schedule()->get_date() : $scheduled_date;
+
+ if ( ! $next ) {
+ $next = date_create();
+ }
+
+ ActionScheduler_TimezoneHelper::set_local_timezone( $next );
+ return $next->format( 'Y-m-d H:i:s' );
+ }
+
+ /**
+ * Validate that we could decode action arguments.
+ *
+ * @param mixed $args The decoded arguments.
+ * @param int $action_id The action ID.
+ *
+ * @throws ActionScheduler_InvalidActionException When the decoded arguments are invalid.
+ */
+ protected function validate_args( $args, $action_id ) {
+ // Ensure we have an array of args.
+ if ( ! is_array( $args ) ) {
+ throw ActionScheduler_InvalidActionException::from_decoding_args( $action_id );
+ }
+
+ // Validate JSON decoding if possible.
+ if ( function_exists( 'json_last_error' ) && JSON_ERROR_NONE !== json_last_error() ) {
+ throw ActionScheduler_InvalidActionException::from_decoding_args( $action_id, $args );
+ }
+ }
+
+ /**
+ * Validate a ActionScheduler_Schedule object.
+ *
+ * @param mixed $schedule The unserialized ActionScheduler_Schedule object.
+ * @param int $action_id The action ID.
+ *
+ * @throws ActionScheduler_InvalidActionException When the schedule is invalid.
+ */
+ protected function validate_schedule( $schedule, $action_id ) {
+ if ( empty( $schedule ) || ! is_a( $schedule, 'ActionScheduler_Schedule' ) ) {
+ throw ActionScheduler_InvalidActionException::from_schedule( $action_id, $schedule );
+ }
+ }
+
+ /**
+ * InnoDB indexes have a maximum size of 767 bytes by default, which is only 191 characters with utf8mb4.
+ *
+ * Previously, AS wasn't concerned about args length, as we used the (unindex) post_content column. However,
+ * with custom tables, we use an indexed VARCHAR column instead.
+ *
+ * @param ActionScheduler_Action $action Action to be validated.
+ * @throws InvalidArgumentException When json encoded args is too long.
+ */
+ protected function validate_action( ActionScheduler_Action $action ) {
+ if ( strlen( wp_json_encode( $action->get_args() ) ) > static::$max_args_length ) {
+ // translators: %d is a number (maximum length of action arguments).
+ throw new InvalidArgumentException( sprintf( __( 'ActionScheduler_Action::$args too long. To ensure the args column can be indexed, action args should not be more than %d characters when encoded as JSON.', 'action-scheduler' ), static::$max_args_length ) );
+ }
+ }
+
+ /**
+ * Cancel pending actions by hook.
+ *
+ * @since 3.0.0
+ *
+ * @param string $hook Hook name.
+ *
+ * @return void
+ */
+ public function cancel_actions_by_hook( $hook ) {
+ $action_ids = true;
+ while ( ! empty( $action_ids ) ) {
+ $action_ids = $this->query_actions(
+ array(
+ 'hook' => $hook,
+ 'status' => self::STATUS_PENDING,
+ 'per_page' => 1000,
+ 'orderby' => 'none',
+ )
+ );
+
+ $this->bulk_cancel_actions( $action_ids );
+ }
+ }
+
+ /**
+ * Cancel pending actions by group.
+ *
+ * @since 3.0.0
+ *
+ * @param string $group Group slug.
+ *
+ * @return void
+ */
+ public function cancel_actions_by_group( $group ) {
+ $action_ids = true;
+ while ( ! empty( $action_ids ) ) {
+ $action_ids = $this->query_actions(
+ array(
+ 'group' => $group,
+ 'status' => self::STATUS_PENDING,
+ 'per_page' => 1000,
+ 'orderby' => 'none',
+ )
+ );
+
+ $this->bulk_cancel_actions( $action_ids );
+ }
+ }
+
+ /**
+ * Cancel a set of action IDs.
+ *
+ * @since 3.0.0
+ *
+ * @param int[] $action_ids List of action IDs.
+ *
+ * @return void
+ */
+ private function bulk_cancel_actions( $action_ids ) {
+ foreach ( $action_ids as $action_id ) {
+ $this->cancel_action( $action_id );
+ }
+
+ do_action( 'action_scheduler_bulk_cancel_actions', $action_ids );
+ }
+
+ /**
+ * Get status labels.
+ *
+ * @return array
+ */
+ public function get_status_labels() {
+ return array(
+ self::STATUS_COMPLETE => __( 'Complete', 'action-scheduler' ),
+ self::STATUS_PENDING => __( 'Pending', 'action-scheduler' ),
+ self::STATUS_RUNNING => __( 'In-progress', 'action-scheduler' ),
+ self::STATUS_FAILED => __( 'Failed', 'action-scheduler' ),
+ self::STATUS_CANCELED => __( 'Canceled', 'action-scheduler' ),
+ );
+ }
+
+ /**
+ * Check if there are any pending scheduled actions due to run.
+ *
+ * @return string
+ */
+ public function has_pending_actions_due() {
+ $pending_actions = $this->query_actions(
+ array(
+ 'per_page' => 1,
+ 'date' => as_get_datetime_object(),
+ 'status' => self::STATUS_PENDING,
+ 'orderby' => 'none',
+ ),
+ 'count'
+ );
+
+ return ! empty( $pending_actions );
+ }
+
+ /**
+ * Callable initialization function optionally overridden in derived classes.
+ */
+ public function init() {}
+
+ /**
+ * Callable function to mark an action as migrated optionally overridden in derived classes.
+ *
+ * @param int $action_id Action ID.
+ */
+ public function mark_migrated( $action_id ) {}
+
+ /**
+ * Get instance.
+ *
+ * @return ActionScheduler_Store
+ */
+ public static function instance() {
+ if ( empty( self::$store ) ) {
+ $class = apply_filters( 'action_scheduler_store_class', self::DEFAULT_CLASS );
+ self::$store = new $class();
+ }
+ return self::$store;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_TimezoneHelper.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_TimezoneHelper.php
new file mode 100755
index 00000000..63813eba
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_TimezoneHelper.php
@@ -0,0 +1,162 @@
+format( 'U' ) );
+ }
+
+ if ( get_option( 'timezone_string' ) ) {
+ $date->setTimezone( new DateTimeZone( self::get_local_timezone_string() ) );
+ } else {
+ $date->setUtcOffset( self::get_local_timezone_offset() );
+ }
+
+ return $date;
+ }
+
+ /**
+ * Helper to retrieve the timezone string for a site until a WP core method exists
+ * (see https://core.trac.wordpress.org/ticket/24730).
+ *
+ * Adapted from wc_timezone_string() and https://secure.php.net/manual/en/function.timezone-name-from-abbr.php#89155.
+ *
+ * If no timezone string is set, and its not possible to match the UTC offset set for the site to a timezone
+ * string, then an empty string will be returned, and the UTC offset should be used to set a DateTime's
+ * timezone.
+ *
+ * @since 2.1.0
+ * @param bool $reset Unused.
+ * @return string PHP timezone string for the site or empty if no timezone string is available.
+ */
+ protected static function get_local_timezone_string( $reset = false ) {
+ // If site timezone string exists, return it.
+ $timezone = get_option( 'timezone_string' );
+ if ( $timezone ) {
+ return $timezone;
+ }
+
+ // Get UTC offset, if it isn't set then return UTC.
+ $utc_offset = intval( get_option( 'gmt_offset', 0 ) );
+ if ( 0 === $utc_offset ) {
+ return 'UTC';
+ }
+
+ // Adjust UTC offset from hours to seconds.
+ $utc_offset *= 3600;
+
+ // Attempt to guess the timezone string from the UTC offset.
+ $timezone = timezone_name_from_abbr( '', $utc_offset );
+ if ( $timezone ) {
+ return $timezone;
+ }
+
+ // Last try, guess timezone string manually.
+ foreach ( timezone_abbreviations_list() as $abbr ) {
+ foreach ( $abbr as $city ) {
+ if ( (bool) date( 'I' ) === (bool) $city['dst'] && $city['timezone_id'] && intval( $city['offset'] ) === $utc_offset ) { // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date -- we are actually interested in the runtime timezone.
+ return $city['timezone_id'];
+ }
+ }
+ }
+
+ // No timezone string.
+ return '';
+ }
+
+ /**
+ * Get timezone offset in seconds.
+ *
+ * @since 2.1.0
+ * @return float
+ */
+ protected static function get_local_timezone_offset() {
+ $timezone = get_option( 'timezone_string' );
+
+ if ( $timezone ) {
+ $timezone_object = new DateTimeZone( $timezone );
+ return $timezone_object->getOffset( new DateTime( 'now' ) );
+ } else {
+ return floatval( get_option( 'gmt_offset', 0 ) ) * HOUR_IN_SECONDS;
+ }
+ }
+
+ /**
+ * Get local timezone.
+ *
+ * @param bool $reset Toggle to discard stored value.
+ * @deprecated 2.1.0
+ */
+ public static function get_local_timezone( $reset = false ) {
+ _deprecated_function( __FUNCTION__, '2.1.0', 'ActionScheduler_TimezoneHelper::set_local_timezone()' );
+ if ( $reset ) {
+ self::$local_timezone = null;
+ }
+ if ( ! isset( self::$local_timezone ) ) {
+ $tzstring = get_option( 'timezone_string' );
+
+ if ( empty( $tzstring ) ) {
+ $gmt_offset = absint( get_option( 'gmt_offset' ) );
+ if ( 0 === $gmt_offset ) {
+ $tzstring = 'UTC';
+ } else {
+ $gmt_offset *= HOUR_IN_SECONDS;
+ $tzstring = timezone_name_from_abbr( '', $gmt_offset, 1 );
+
+ // If there's no timezone string, try again with no DST.
+ if ( false === $tzstring ) {
+ $tzstring = timezone_name_from_abbr( '', $gmt_offset, 0 );
+ }
+
+ // Try mapping to the first abbreviation we can find.
+ if ( false === $tzstring ) {
+ $is_dst = date( 'I' ); // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date -- we are actually interested in the runtime timezone.
+ foreach ( timezone_abbreviations_list() as $abbr ) {
+ foreach ( $abbr as $city ) {
+ if ( $city['dst'] === $is_dst && $city['offset'] === $gmt_offset ) {
+ // If there's no valid timezone ID, keep looking.
+ if ( is_null( $city['timezone_id'] ) ) {
+ continue;
+ }
+
+ $tzstring = $city['timezone_id'];
+ break 2;
+ }
+ }
+ }
+ }
+
+ // If we still have no valid string, then fall back to UTC.
+ if ( false === $tzstring ) {
+ $tzstring = 'UTC';
+ }
+ }
+ }
+
+ self::$local_timezone = new DateTimeZone( $tzstring );
+ }
+ return self::$local_timezone;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_WPCLI_Command.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_WPCLI_Command.php
new file mode 100755
index 00000000..847c109e
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_WPCLI_Command.php
@@ -0,0 +1,83 @@
+
+ */
+ protected $assoc_args;
+
+ /**
+ * Construct.
+ *
+ * @param string[] $args Positional arguments.
+ * @param array $assoc_args Keyed arguments.
+ * @throws \Exception When loading a CLI command file outside of WP CLI context.
+ */
+ public function __construct( array $args, array $assoc_args ) {
+ if ( ! defined( 'WP_CLI' ) || ! constant( 'WP_CLI' ) ) {
+ /* translators: %s php class name */
+ throw new \Exception( sprintf( __( 'The %s class can only be run within WP CLI.', 'action-scheduler' ), get_class( $this ) ) );
+ }
+
+ $this->args = $args;
+ $this->assoc_args = $assoc_args;
+ }
+
+ /**
+ * Execute command.
+ */
+ abstract public function execute();
+
+ /**
+ * Get the scheduled date in a human friendly format.
+ *
+ * @see ActionScheduler_ListTable::get_schedule_display_string()
+ * @param ActionScheduler_Schedule $schedule Schedule.
+ * @return string
+ */
+ protected function get_schedule_display_string( ActionScheduler_Schedule $schedule ) {
+
+ $schedule_display_string = '';
+
+ if ( ! $schedule->get_date() ) {
+ return '0000-00-00 00:00:00';
+ }
+
+ $next_timestamp = $schedule->get_date()->getTimestamp();
+
+ $schedule_display_string .= $schedule->get_date()->format( static::DATE_FORMAT );
+
+ return $schedule_display_string;
+ }
+
+ /**
+ * Transforms arguments with '__' from CSV into expected arrays.
+ *
+ * @see \WP_CLI\CommandWithDBObject::process_csv_arguments_to_arrays()
+ * @link https://github.com/wp-cli/entity-command/blob/c270cc9a2367cb8f5845f26a6b5e203397c91392/src/WP_CLI/CommandWithDBObject.php#L99
+ * @return void
+ */
+ protected function process_csv_arguments_to_arrays() {
+ foreach ( $this->assoc_args as $k => $v ) {
+ if ( false !== strpos( $k, '__' ) ) {
+ $this->assoc_args[ $k ] = explode( ',', $v );
+ }
+ }
+ }
+
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/actions/ActionScheduler_Action.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/actions/ActionScheduler_Action.php
new file mode 100755
index 00000000..1613efa1
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/actions/ActionScheduler_Action.php
@@ -0,0 +1,191 @@
+
+ */
+ protected $args = array();
+
+ /**
+ * Action's schedule.
+ *
+ * @var ActionScheduler_Schedule
+ */
+ protected $schedule = null;
+
+ /**
+ * Action's group.
+ *
+ * @var string
+ */
+ protected $group = '';
+
+ /**
+ * Priorities are conceptually similar to those used for regular WordPress actions.
+ * Like those, a lower priority takes precedence over a higher priority and the default
+ * is 10.
+ *
+ * Unlike regular WordPress actions, the priority of a scheduled action is strictly an
+ * integer and should be kept within the bounds 0-255 (anything outside the bounds will
+ * be brought back into the acceptable range).
+ *
+ * @var int
+ */
+ protected $priority = 10;
+
+ /**
+ * Construct.
+ *
+ * @param string $hook Action's hook.
+ * @param mixed[] $args Action's arguments.
+ * @param null|ActionScheduler_Schedule $schedule Action's schedule.
+ * @param string $group Action's group.
+ */
+ public function __construct( $hook, array $args = array(), ?ActionScheduler_Schedule $schedule = null, $group = '' ) {
+ $schedule = empty( $schedule ) ? new ActionScheduler_NullSchedule() : $schedule;
+ $this->set_hook( $hook );
+ $this->set_schedule( $schedule );
+ $this->set_args( $args );
+ $this->set_group( $group );
+ }
+
+ /**
+ * Executes the action.
+ *
+ * If no callbacks are registered, an exception will be thrown and the action will not be
+ * fired. This is useful to help detect cases where the code responsible for setting up
+ * a scheduled action no longer exists.
+ *
+ * @throws Exception If no callbacks are registered for this action.
+ */
+ public function execute() {
+ $hook = $this->get_hook();
+
+ if ( ! has_action( $hook ) ) {
+ throw new Exception(
+ sprintf(
+ /* translators: 1: action hook. */
+ __( 'Scheduled action for %1$s will not be executed as no callbacks are registered.', 'action-scheduler' ),
+ $hook
+ )
+ );
+ }
+
+ do_action_ref_array( $hook, array_values( $this->get_args() ) );
+ }
+
+ /**
+ * Set action's hook.
+ *
+ * @param string $hook Action's hook.
+ */
+ protected function set_hook( $hook ) {
+ $this->hook = $hook;
+ }
+
+ /**
+ * Get action's hook.
+ */
+ public function get_hook() {
+ return $this->hook;
+ }
+
+ /**
+ * Set action's schedule.
+ *
+ * @param ActionScheduler_Schedule $schedule Action's schedule.
+ */
+ protected function set_schedule( ActionScheduler_Schedule $schedule ) {
+ $this->schedule = $schedule;
+ }
+
+ /**
+ * Action's schedule.
+ *
+ * @return ActionScheduler_Schedule
+ */
+ public function get_schedule() {
+ return $this->schedule;
+ }
+
+ /**
+ * Set action's args.
+ *
+ * @param mixed[] $args Action's arguments.
+ */
+ protected function set_args( array $args ) {
+ $this->args = $args;
+ }
+
+ /**
+ * Get action's args.
+ */
+ public function get_args() {
+ return $this->args;
+ }
+
+ /**
+ * Section action's group.
+ *
+ * @param string $group Action's group.
+ */
+ protected function set_group( $group ) {
+ $this->group = $group;
+ }
+
+ /**
+ * Action's group.
+ *
+ * @return string
+ */
+ public function get_group() {
+ return $this->group;
+ }
+
+ /**
+ * Action has not finished.
+ *
+ * @return bool
+ */
+ public function is_finished() {
+ return false;
+ }
+
+ /**
+ * Sets the priority of the action.
+ *
+ * @param int $priority Priority level (lower is higher priority). Should be in the range 0-255.
+ *
+ * @return void
+ */
+ public function set_priority( $priority ) {
+ if ( $priority < 0 ) {
+ $priority = 0;
+ } elseif ( $priority > 255 ) {
+ $priority = 255;
+ }
+
+ $this->priority = (int) $priority;
+ }
+
+ /**
+ * Gets the action priority.
+ *
+ * @return int
+ */
+ public function get_priority() {
+ return $this->priority;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/actions/ActionScheduler_CanceledAction.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/actions/ActionScheduler_CanceledAction.php
new file mode 100755
index 00000000..c6007528
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/actions/ActionScheduler_CanceledAction.php
@@ -0,0 +1,25 @@
+set_schedule( new ActionScheduler_NullSchedule() );
+ }
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/actions/ActionScheduler_FinishedAction.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/actions/ActionScheduler_FinishedAction.php
new file mode 100755
index 00000000..d4e89421
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/actions/ActionScheduler_FinishedAction.php
@@ -0,0 +1,21 @@
+set_schedule( new ActionScheduler_NullSchedule() );
+ }
+
+ /**
+ * Execute action.
+ */
+ public function execute() {
+ // don't execute.
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_DBLogger.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_DBLogger.php
new file mode 100755
index 00000000..0976b066
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_DBLogger.php
@@ -0,0 +1,154 @@
+format( 'Y-m-d H:i:s' );
+ ActionScheduler_TimezoneHelper::set_local_timezone( $date );
+ $date_local = $date->format( 'Y-m-d H:i:s' );
+
+ /** @var \wpdb $wpdb */ //phpcs:ignore Generic.Commenting.DocComment.MissingShort
+ global $wpdb;
+ $wpdb->insert(
+ $wpdb->actionscheduler_logs,
+ array(
+ 'action_id' => $action_id,
+ 'message' => $message,
+ 'log_date_gmt' => $date_gmt,
+ 'log_date_local' => $date_local,
+ ),
+ array( '%d', '%s', '%s', '%s' )
+ );
+
+ return $wpdb->insert_id;
+ }
+
+ /**
+ * Retrieve an action log entry.
+ *
+ * @param int $entry_id Log entry ID.
+ *
+ * @return ActionScheduler_LogEntry
+ */
+ public function get_entry( $entry_id ) {
+ /** @var \wpdb $wpdb */ //phpcs:ignore Generic.Commenting.DocComment.MissingShort
+ global $wpdb;
+ $entry = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->actionscheduler_logs} WHERE log_id=%d", $entry_id ) );
+
+ return $this->create_entry_from_db_record( $entry );
+ }
+
+ /**
+ * Create an action log entry from a database record.
+ *
+ * @param object $record Log entry database record object.
+ *
+ * @return ActionScheduler_LogEntry
+ */
+ private function create_entry_from_db_record( $record ) {
+ if ( empty( $record ) ) {
+ return new ActionScheduler_NullLogEntry();
+ }
+
+ if ( is_null( $record->log_date_gmt ) ) {
+ $date = as_get_datetime_object( ActionScheduler_StoreSchema::DEFAULT_DATE );
+ } else {
+ $date = as_get_datetime_object( $record->log_date_gmt );
+ }
+
+ return new ActionScheduler_LogEntry( $record->action_id, $record->message, $date );
+ }
+
+ /**
+ * Retrieve an action's log entries from the database.
+ *
+ * @param int $action_id Action ID.
+ *
+ * @return ActionScheduler_LogEntry[]
+ */
+ public function get_logs( $action_id ) {
+ /** @var \wpdb $wpdb */ //phpcs:ignore Generic.Commenting.DocComment.MissingShort
+ global $wpdb;
+
+ $records = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->actionscheduler_logs} WHERE action_id=%d", $action_id ) );
+
+ return array_map( array( $this, 'create_entry_from_db_record' ), $records );
+ }
+
+ /**
+ * Initialize the data store.
+ *
+ * @codeCoverageIgnore
+ */
+ public function init() {
+ $table_maker = new ActionScheduler_LoggerSchema();
+ $table_maker->init();
+ $table_maker->register_tables();
+
+ parent::init();
+
+ add_action( 'action_scheduler_deleted_action', array( $this, 'clear_deleted_action_logs' ), 10, 1 );
+ }
+
+ /**
+ * Delete the action logs for an action.
+ *
+ * @param int $action_id Action ID.
+ */
+ public function clear_deleted_action_logs( $action_id ) {
+ /** @var \wpdb $wpdb */ //phpcs:ignore Generic.Commenting.DocComment.MissingShort
+ global $wpdb;
+ $wpdb->delete( $wpdb->actionscheduler_logs, array( 'action_id' => $action_id ), array( '%d' ) );
+ }
+
+ /**
+ * Bulk add cancel action log entries.
+ *
+ * @param array $action_ids List of action ID.
+ */
+ public function bulk_log_cancel_actions( $action_ids ) {
+ if ( empty( $action_ids ) ) {
+ return;
+ }
+
+ /** @var \wpdb $wpdb */ //phpcs:ignore Generic.Commenting.DocComment.MissingShort
+ global $wpdb;
+ $date = as_get_datetime_object();
+ $date_gmt = $date->format( 'Y-m-d H:i:s' );
+ ActionScheduler_TimezoneHelper::set_local_timezone( $date );
+ $date_local = $date->format( 'Y-m-d H:i:s' );
+ $message = __( 'action canceled', 'action-scheduler' );
+ $format = '(%d, ' . $wpdb->prepare( '%s, %s, %s', $message, $date_gmt, $date_local ) . ')';
+ $sql_query = "INSERT {$wpdb->actionscheduler_logs} (action_id, message, log_date_gmt, log_date_local) VALUES ";
+ $value_rows = array();
+
+ foreach ( $action_ids as $action_id ) {
+ $value_rows[] = $wpdb->prepare( $format, $action_id ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
+ }
+ $sql_query .= implode( ',', $value_rows );
+
+ $wpdb->query( $sql_query ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_DBStore.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_DBStore.php
new file mode 100755
index 00000000..7840fe25
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_DBStore.php
@@ -0,0 +1,1342 @@
+ '',
+ 'hooks' => '',
+ 'exclude-groups' => '',
+ );
+
+ /**
+ * Initialize the data store
+ *
+ * @codeCoverageIgnore
+ */
+ public function init() {
+ $table_maker = new ActionScheduler_StoreSchema();
+ $table_maker->init();
+ $table_maker->register_tables();
+ }
+
+ /**
+ * Save an action, checks if this is a unique action before actually saving.
+ *
+ * @param ActionScheduler_Action $action Action object.
+ * @param DateTime|null $scheduled_date Optional schedule date. Default null.
+ *
+ * @return int Action ID.
+ * @throws RuntimeException Throws exception when saving the action fails.
+ */
+ public function save_unique_action( ActionScheduler_Action $action, ?DateTime $scheduled_date = null ) {
+ return $this->save_action_to_db( $action, $scheduled_date, true );
+ }
+
+ /**
+ * Save an action. Can save duplicate action as well, prefer using `save_unique_action` instead.
+ *
+ * @param ActionScheduler_Action $action Action object.
+ * @param DateTime|null $scheduled_date Optional schedule date. Default null.
+ *
+ * @return int Action ID.
+ * @throws RuntimeException Throws exception when saving the action fails.
+ */
+ public function save_action( ActionScheduler_Action $action, ?DateTime $scheduled_date = null ) {
+ return $this->save_action_to_db( $action, $scheduled_date, false );
+ }
+
+ /**
+ * Save an action.
+ *
+ * @param ActionScheduler_Action $action Action object.
+ * @param ?DateTime $date Optional schedule date. Default null.
+ * @param bool $unique Whether the action should be unique.
+ *
+ * @return int Action ID.
+ * @throws \RuntimeException Throws exception when saving the action fails.
+ */
+ private function save_action_to_db( ActionScheduler_Action $action, ?DateTime $date = null, $unique = false ) {
+ global $wpdb;
+
+ try {
+ $this->validate_action( $action );
+
+ $data = array(
+ 'hook' => $action->get_hook(),
+ 'status' => ( $action->is_finished() ? self::STATUS_COMPLETE : self::STATUS_PENDING ),
+ 'scheduled_date_gmt' => $this->get_scheduled_date_string( $action, $date ),
+ 'scheduled_date_local' => $this->get_scheduled_date_string_local( $action, $date ),
+ 'schedule' => serialize( $action->get_schedule() ), // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize
+ 'group_id' => current( $this->get_group_ids( $action->get_group() ) ),
+ 'priority' => $action->get_priority(),
+ );
+
+ $args = wp_json_encode( $action->get_args() );
+ if ( strlen( $args ) <= static::$max_index_length ) {
+ $data['args'] = $args;
+ } else {
+ $data['args'] = $this->hash_args( $args );
+ $data['extended_args'] = $args;
+ }
+
+ $insert_sql = $this->build_insert_sql( $data, $unique );
+
+ // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- $insert_sql should be already prepared.
+ $wpdb->query( $insert_sql );
+ $action_id = $wpdb->insert_id;
+
+ if ( is_wp_error( $action_id ) ) {
+ throw new \RuntimeException( $action_id->get_error_message() );
+ } elseif ( empty( $action_id ) ) {
+ if ( $unique ) {
+ return 0;
+ }
+ throw new \RuntimeException( $wpdb->last_error ? $wpdb->last_error : __( 'Database error.', 'action-scheduler' ) );
+ }
+
+ do_action( 'action_scheduler_stored_action', $action_id );
+
+ return $action_id;
+ } catch ( \Exception $e ) {
+ /* translators: %s: error message */
+ throw new \RuntimeException( sprintf( __( 'Error saving action: %s', 'action-scheduler' ), $e->getMessage() ), 0 );
+ }
+ }
+
+ /**
+ * Helper function to build insert query.
+ *
+ * @param array $data Row data for action.
+ * @param bool $unique Whether the action should be unique.
+ *
+ * @return string Insert query.
+ */
+ private function build_insert_sql( array $data, $unique ) {
+ global $wpdb;
+
+ $columns = array_keys( $data );
+ $values = array_values( $data );
+ $placeholders = array_map( array( $this, 'get_placeholder_for_column' ), $columns );
+
+ $table_name = ! empty( $wpdb->actionscheduler_actions ) ? $wpdb->actionscheduler_actions : $wpdb->prefix . 'actionscheduler_actions';
+
+ $column_sql = '`' . implode( '`, `', $columns ) . '`';
+ $placeholder_sql = implode( ', ', $placeholders );
+ $where_clause = $this->build_where_clause_for_insert( $data, $table_name, $unique );
+
+ // phpcs:disable WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare -- $column_sql and $where_clause are already prepared. $placeholder_sql is hardcoded.
+ $insert_query = $wpdb->prepare(
+ "
+INSERT INTO $table_name ( $column_sql )
+SELECT $placeholder_sql FROM DUAL
+WHERE ( $where_clause ) IS NULL",
+ $values
+ );
+ // phpcs:enable
+
+ return $insert_query;
+ }
+
+ /**
+ * Helper method to build where clause for action insert statement.
+ *
+ * @param array $data Row data for action.
+ * @param string $table_name Action table name.
+ * @param bool $unique Where action should be unique.
+ *
+ * @return string Where clause to be used with insert.
+ */
+ private function build_where_clause_for_insert( $data, $table_name, $unique ) {
+ global $wpdb;
+
+ if ( ! $unique ) {
+ return 'SELECT NULL FROM DUAL';
+ }
+
+ $pending_statuses = array(
+ ActionScheduler_Store::STATUS_PENDING,
+ ActionScheduler_Store::STATUS_RUNNING,
+ );
+ $pending_status_placeholders = implode( ', ', array_fill( 0, count( $pending_statuses ), '%s' ) );
+
+ // phpcs:disable WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.ReplacementsWrongNumber -- $pending_status_placeholders is hardcoded.
+ $where_clause = $wpdb->prepare(
+ "
+SELECT action_id FROM $table_name
+WHERE status IN ( $pending_status_placeholders )
+AND hook = %s
+AND `group_id` = %d
+",
+ array_merge(
+ $pending_statuses,
+ array(
+ $data['hook'],
+ $data['group_id'],
+ )
+ )
+ );
+ // phpcs:enable
+
+ return "$where_clause" . ' LIMIT 1';
+ }
+
+ /**
+ * Helper method to get $wpdb->prepare placeholder for a given column name.
+ *
+ * @param string $column_name Name of column in actions table.
+ *
+ * @return string Placeholder to use for given column.
+ */
+ private function get_placeholder_for_column( $column_name ) {
+ $string_columns = array(
+ 'hook',
+ 'status',
+ 'scheduled_date_gmt',
+ 'scheduled_date_local',
+ 'args',
+ 'schedule',
+ 'last_attempt_gmt',
+ 'last_attempt_local',
+ 'extended_args',
+ );
+
+ return in_array( $column_name, $string_columns, true ) ? '%s' : '%d';
+ }
+
+ /**
+ * Generate a hash from json_encoded $args using MD5 as this isn't for security.
+ *
+ * @param string $args JSON encoded action args.
+ * @return string
+ */
+ protected function hash_args( $args ) {
+ return md5( $args );
+ }
+
+ /**
+ * Get action args query param value from action args.
+ *
+ * @param array $args Action args.
+ * @return string
+ */
+ protected function get_args_for_query( $args ) {
+ $encoded = wp_json_encode( $args );
+ if ( strlen( $encoded ) <= static::$max_index_length ) {
+ return $encoded;
+ }
+ return $this->hash_args( $encoded );
+ }
+ /**
+ * Get a group's ID based on its name/slug.
+ *
+ * @param string|array $slugs The string name of a group, or names for several groups.
+ * @param bool $create_if_not_exists Whether to create the group if it does not already exist. Default, true - create the group.
+ *
+ * @return array The group IDs, if they exist or were successfully created. May be empty.
+ */
+ protected function get_group_ids( $slugs, $create_if_not_exists = true ) {
+ $slugs = (array) $slugs;
+ $group_ids = array();
+
+ if ( empty( $slugs ) ) {
+ return array();
+ }
+
+ /**
+ * Global.
+ *
+ * @var \wpdb $wpdb
+ */
+ global $wpdb;
+
+ foreach ( $slugs as $slug ) {
+ $group_id = (int) $wpdb->get_var( $wpdb->prepare( "SELECT group_id FROM {$wpdb->actionscheduler_groups} WHERE slug=%s", $slug ) );
+
+ if ( empty( $group_id ) && $create_if_not_exists ) {
+ $group_id = $this->create_group( $slug );
+ }
+
+ if ( $group_id ) {
+ $group_ids[] = $group_id;
+ }
+ }
+
+ return $group_ids;
+ }
+
+ /**
+ * Create an action group.
+ *
+ * @param string $slug Group slug.
+ *
+ * @return int Group ID.
+ */
+ protected function create_group( $slug ) {
+ /**
+ * Global.
+ *
+ * @var \wpdb $wpdb
+ */
+ global $wpdb;
+
+ $wpdb->insert( $wpdb->actionscheduler_groups, array( 'slug' => $slug ) );
+
+ return (int) $wpdb->insert_id;
+ }
+
+ /**
+ * Retrieve an action.
+ *
+ * @param int $action_id Action ID.
+ *
+ * @return ActionScheduler_Action
+ */
+ public function fetch_action( $action_id ) {
+ /**
+ * Global.
+ *
+ * @var \wpdb $wpdb
+ */
+ global $wpdb;
+
+ $data = $wpdb->get_row(
+ $wpdb->prepare(
+ "SELECT a.*, g.slug AS `group` FROM {$wpdb->actionscheduler_actions} a LEFT JOIN {$wpdb->actionscheduler_groups} g ON a.group_id=g.group_id WHERE a.action_id=%d",
+ $action_id
+ )
+ );
+
+ if ( empty( $data ) ) {
+ return $this->get_null_action();
+ }
+
+ if ( ! empty( $data->extended_args ) ) {
+ $data->args = $data->extended_args;
+ unset( $data->extended_args );
+ }
+
+ // Convert NULL dates to zero dates.
+ $date_fields = array(
+ 'scheduled_date_gmt',
+ 'scheduled_date_local',
+ 'last_attempt_gmt',
+ 'last_attempt_gmt',
+ );
+ foreach ( $date_fields as $date_field ) {
+ if ( is_null( $data->$date_field ) ) {
+ $data->$date_field = ActionScheduler_StoreSchema::DEFAULT_DATE;
+ }
+ }
+
+ try {
+ $action = $this->make_action_from_db_record( $data );
+ } catch ( ActionScheduler_InvalidActionException $exception ) {
+ do_action( 'action_scheduler_failed_fetch_action', $action_id, $exception );
+ return $this->get_null_action();
+ }
+
+ return $action;
+ }
+
+ /**
+ * Create a null action.
+ *
+ * @return ActionScheduler_NullAction
+ */
+ protected function get_null_action() {
+ return new ActionScheduler_NullAction();
+ }
+
+ /**
+ * Create an action from a database record.
+ *
+ * @param object $data Action database record.
+ *
+ * @return ActionScheduler_Action|ActionScheduler_CanceledAction|ActionScheduler_FinishedAction
+ */
+ protected function make_action_from_db_record( $data ) {
+
+ $hook = $data->hook;
+ $args = json_decode( $data->args, true );
+ $schedule = unserialize( $data->schedule ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_unserialize
+
+ $this->validate_args( $args, $data->action_id );
+ $this->validate_schedule( $schedule, $data->action_id );
+
+ if ( empty( $schedule ) ) {
+ $schedule = new ActionScheduler_NullSchedule();
+ }
+ $group = $data->group ? $data->group : '';
+
+ return ActionScheduler::factory()->get_stored_action( $data->status, $data->hook, $args, $schedule, $group, $data->priority );
+ }
+
+ /**
+ * Returns the SQL statement to query (or count) actions.
+ *
+ * @since 3.3.0 $query['status'] accepts array of statuses instead of a single status.
+ *
+ * @param array $query Filtering options.
+ * @param string $select_or_count Whether the SQL should select and return the IDs or just the row count.
+ *
+ * @return string SQL statement already properly escaped.
+ * @throws \InvalidArgumentException If the query is invalid.
+ * @throws \RuntimeException When "unknown partial args matching value".
+ */
+ protected function get_query_actions_sql( array $query, $select_or_count = 'select' ) {
+
+ if ( ! in_array( $select_or_count, array( 'select', 'count' ), true ) ) {
+ throw new InvalidArgumentException( __( 'Invalid value for select or count parameter. Cannot query actions.', 'action-scheduler' ) );
+ }
+
+ $query = wp_parse_args(
+ $query,
+ array(
+ 'hook' => '',
+ 'args' => null,
+ 'partial_args_matching' => 'off', // can be 'like' or 'json'.
+ 'date' => null,
+ 'date_compare' => '<=',
+ 'modified' => null,
+ 'modified_compare' => '<=',
+ 'group' => '',
+ 'status' => '',
+ 'claimed' => null,
+ 'per_page' => 5,
+ 'offset' => 0,
+ 'orderby' => 'date',
+ 'order' => 'ASC',
+ )
+ );
+
+ /**
+ * Global.
+ *
+ * @var \wpdb $wpdb
+ */
+ global $wpdb;
+
+ $db_server_info = is_callable( array( $wpdb, 'db_server_info' ) ) ? $wpdb->db_server_info() : $wpdb->db_version();
+ if ( false !== strpos( $db_server_info, 'MariaDB' ) ) {
+ $supports_json = version_compare(
+ PHP_VERSION_ID >= 80016 ? $wpdb->db_version() : preg_replace( '/[^0-9.].*/', '', str_replace( '5.5.5-', '', $db_server_info ) ),
+ '10.2',
+ '>='
+ );
+ } else {
+ $supports_json = version_compare( $wpdb->db_version(), '5.7', '>=' );
+ }
+
+ $sql = ( 'count' === $select_or_count ) ? 'SELECT count(a.action_id)' : 'SELECT a.action_id';
+ $sql .= " FROM {$wpdb->actionscheduler_actions} a";
+ $sql_params = array();
+
+ if ( ! empty( $query['group'] ) || 'group' === $query['orderby'] ) {
+ $sql .= " LEFT JOIN {$wpdb->actionscheduler_groups} g ON g.group_id=a.group_id";
+ }
+
+ $sql .= ' WHERE 1=1';
+
+ if ( ! empty( $query['group'] ) ) {
+ $sql .= ' AND g.slug=%s';
+ $sql_params[] = $query['group'];
+ }
+
+ if ( ! empty( $query['hook'] ) ) {
+ $sql .= ' AND a.hook=%s';
+ $sql_params[] = $query['hook'];
+ }
+
+ if ( ! is_null( $query['args'] ) ) {
+ switch ( $query['partial_args_matching'] ) {
+ case 'json':
+ if ( ! $supports_json ) {
+ throw new \RuntimeException( __( 'JSON partial matching not supported in your environment. Please check your MySQL/MariaDB version.', 'action-scheduler' ) );
+ }
+ $supported_types = array(
+ 'integer' => '%d',
+ 'boolean' => '%s',
+ 'double' => '%f',
+ 'string' => '%s',
+ );
+ foreach ( $query['args'] as $key => $value ) {
+ $value_type = gettype( $value );
+ if ( 'boolean' === $value_type ) {
+ $value = $value ? 'true' : 'false';
+ }
+ $placeholder = isset( $supported_types[ $value_type ] ) ? $supported_types[ $value_type ] : false;
+ if ( ! $placeholder ) {
+ throw new \RuntimeException(
+ sprintf(
+ /* translators: %s: provided value type */
+ __( 'The value type for the JSON partial matching is not supported. Must be either integer, boolean, double or string. %s type provided.', 'action-scheduler' ),
+ $value_type
+ )
+ );
+ }
+ $sql .= ' AND JSON_EXTRACT(a.args, %s)=' . $placeholder;
+ $sql_params[] = '$.' . $key;
+ $sql_params[] = $value;
+ }
+ break;
+ case 'like':
+ foreach ( $query['args'] as $key => $value ) {
+ $sql .= ' AND a.args LIKE %s';
+ $json_partial = $wpdb->esc_like( trim( wp_json_encode( array( $key => $value ) ), '{}' ) );
+ $sql_params[] = "%{$json_partial}%";
+ }
+ break;
+ case 'off':
+ $sql .= ' AND a.args=%s';
+ $sql_params[] = $this->get_args_for_query( $query['args'] );
+ break;
+ default:
+ throw new \RuntimeException( __( 'Unknown partial args matching value.', 'action-scheduler' ) );
+ }
+ }
+
+ if ( $query['status'] ) {
+ $statuses = (array) $query['status'];
+ $placeholders = array_fill( 0, count( $statuses ), '%s' );
+ $sql .= ' AND a.status IN (' . join( ', ', $placeholders ) . ')';
+ $sql_params = array_merge( $sql_params, array_values( $statuses ) );
+ }
+
+ if ( $query['date'] instanceof \DateTime ) {
+ $date = clone $query['date'];
+ $date->setTimezone( new \DateTimeZone( 'UTC' ) );
+ $date_string = $date->format( 'Y-m-d H:i:s' );
+ $comparator = $this->validate_sql_comparator( $query['date_compare'] );
+ $sql .= " AND a.scheduled_date_gmt $comparator %s";
+ $sql_params[] = $date_string;
+ }
+
+ if ( $query['modified'] instanceof \DateTime ) {
+ $modified = clone $query['modified'];
+ $modified->setTimezone( new \DateTimeZone( 'UTC' ) );
+ $date_string = $modified->format( 'Y-m-d H:i:s' );
+ $comparator = $this->validate_sql_comparator( $query['modified_compare'] );
+ $sql .= " AND a.last_attempt_gmt $comparator %s";
+ $sql_params[] = $date_string;
+ }
+
+ if ( true === $query['claimed'] ) {
+ $sql .= ' AND a.claim_id != 0';
+ } elseif ( false === $query['claimed'] ) {
+ $sql .= ' AND a.claim_id = 0';
+ } elseif ( ! is_null( $query['claimed'] ) ) {
+ $sql .= ' AND a.claim_id = %d';
+ $sql_params[] = $query['claimed'];
+ }
+
+ if ( ! empty( $query['search'] ) ) {
+ $sql .= ' AND (a.hook LIKE %s OR (a.extended_args IS NULL AND a.args LIKE %s) OR a.extended_args LIKE %s';
+ for ( $i = 0; $i < 3; $i++ ) {
+ $sql_params[] = sprintf( '%%%s%%', $query['search'] );
+ }
+
+ $search_claim_id = (int) $query['search'];
+ if ( $search_claim_id ) {
+ $sql .= ' OR a.claim_id = %d';
+ $sql_params[] = $search_claim_id;
+ }
+
+ $sql .= ')';
+ }
+
+ if ( 'select' === $select_or_count ) {
+ if ( 'ASC' === strtoupper( $query['order'] ) ) {
+ $order = 'ASC';
+ } else {
+ $order = 'DESC';
+ }
+ switch ( $query['orderby'] ) {
+ case 'hook':
+ $sql .= " ORDER BY a.hook $order";
+ break;
+ case 'group':
+ $sql .= " ORDER BY g.slug $order";
+ break;
+ case 'modified':
+ $sql .= " ORDER BY a.last_attempt_gmt $order";
+ break;
+ case 'none':
+ break;
+ case 'action_id':
+ $sql .= " ORDER BY a.action_id $order";
+ break;
+ case 'date':
+ default:
+ $sql .= " ORDER BY a.scheduled_date_gmt $order";
+ break;
+ }
+
+ if ( $query['per_page'] > 0 ) {
+ $sql .= ' LIMIT %d, %d';
+ $sql_params[] = $query['offset'];
+ $sql_params[] = $query['per_page'];
+ }
+ }
+
+ if ( ! empty( $sql_params ) ) {
+ $sql = $wpdb->prepare( $sql, $sql_params ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
+ }
+
+ return $sql;
+ }
+
+ /**
+ * Query for action count or list of action IDs.
+ *
+ * @since 3.3.0 $query['status'] accepts array of statuses instead of a single status.
+ *
+ * @see ActionScheduler_Store::query_actions for $query arg usage.
+ *
+ * @param array $query Query filtering options.
+ * @param string $query_type Whether to select or count the results. Defaults to select.
+ *
+ * @return string|array|null The IDs of actions matching the query. Null on failure.
+ */
+ public function query_actions( $query = array(), $query_type = 'select' ) {
+ /**
+ * Global.
+ *
+ * @var wpdb $wpdb
+ */
+ global $wpdb;
+
+ $sql = $this->get_query_actions_sql( $query, $query_type );
+
+ return ( 'count' === $query_type ) ? $wpdb->get_var( $sql ) : $wpdb->get_col( $sql ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.NoSql, WordPress.DB.DirectDatabaseQuery.NoCaching
+ }
+
+ /**
+ * Get a count of all actions in the store, grouped by status.
+ *
+ * @return array Set of 'status' => int $count pairs for statuses with 1 or more actions of that status.
+ */
+ public function action_counts() {
+ global $wpdb;
+
+ $sql = "SELECT a.status, count(a.status) as 'count'";
+ $sql .= " FROM {$wpdb->actionscheduler_actions} a";
+ $sql .= ' GROUP BY a.status';
+
+ $actions_count_by_status = array();
+ $action_stati_and_labels = $this->get_status_labels();
+
+ foreach ( $wpdb->get_results( $sql ) as $action_data ) { // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
+ // Ignore any actions with invalid status.
+ if ( array_key_exists( $action_data->status, $action_stati_and_labels ) ) {
+ $actions_count_by_status[ $action_data->status ] = $action_data->count;
+ }
+ }
+
+ return $actions_count_by_status;
+ }
+
+ /**
+ * Cancel an action.
+ *
+ * @param int $action_id Action ID.
+ *
+ * @return void
+ * @throws \InvalidArgumentException If the action update failed.
+ */
+ public function cancel_action( $action_id ) {
+ /**
+ * Global.
+ *
+ * @var \wpdb $wpdb
+ */
+ global $wpdb;
+
+ $updated = $wpdb->update(
+ $wpdb->actionscheduler_actions,
+ array( 'status' => self::STATUS_CANCELED ),
+ array( 'action_id' => $action_id ),
+ array( '%s' ),
+ array( '%d' )
+ );
+ if ( false === $updated ) {
+ /* translators: %s: action ID */
+ throw new \InvalidArgumentException( sprintf( __( 'Unidentified action %s: we were unable to cancel this action. It may may have been deleted by another process.', 'action-scheduler' ), $action_id ) );
+ }
+ do_action( 'action_scheduler_canceled_action', $action_id );
+ }
+
+ /**
+ * Cancel pending actions by hook.
+ *
+ * @since 3.0.0
+ *
+ * @param string $hook Hook name.
+ *
+ * @return void
+ */
+ public function cancel_actions_by_hook( $hook ) {
+ $this->bulk_cancel_actions( array( 'hook' => $hook ) );
+ }
+
+ /**
+ * Cancel pending actions by group.
+ *
+ * @param string $group Group slug.
+ *
+ * @return void
+ */
+ public function cancel_actions_by_group( $group ) {
+ $this->bulk_cancel_actions( array( 'group' => $group ) );
+ }
+
+ /**
+ * Bulk cancel actions.
+ *
+ * @since 3.0.0
+ *
+ * @param array $query_args Query parameters.
+ */
+ protected function bulk_cancel_actions( $query_args ) {
+ /**
+ * Global.
+ *
+ * @var \wpdb $wpdb
+ */
+ global $wpdb;
+
+ if ( ! is_array( $query_args ) ) {
+ return;
+ }
+
+ // Don't cancel actions that are already canceled.
+ if ( isset( $query_args['status'] ) && self::STATUS_CANCELED === $query_args['status'] ) {
+ return;
+ }
+
+ $action_ids = true;
+ $query_args = wp_parse_args(
+ $query_args,
+ array(
+ 'per_page' => 1000,
+ 'status' => self::STATUS_PENDING,
+ 'orderby' => 'none',
+ )
+ );
+
+ while ( $action_ids ) {
+ $action_ids = $this->query_actions( $query_args );
+ if ( empty( $action_ids ) ) {
+ break;
+ }
+
+ $format = array_fill( 0, count( $action_ids ), '%d' );
+ $query_in = '(' . implode( ',', $format ) . ')';
+ $parameters = $action_ids;
+ array_unshift( $parameters, self::STATUS_CANCELED );
+
+ $wpdb->query(
+ $wpdb->prepare(
+ "UPDATE {$wpdb->actionscheduler_actions} SET status = %s WHERE action_id IN {$query_in}", // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
+ $parameters
+ )
+ );
+
+ do_action( 'action_scheduler_bulk_cancel_actions', $action_ids );
+ }
+ }
+
+ /**
+ * Delete an action.
+ *
+ * @param int $action_id Action ID.
+ * @throws \InvalidArgumentException If the action deletion failed.
+ */
+ public function delete_action( $action_id ) {
+ /**
+ * Global.
+ *
+ * @var \wpdb $wpdb
+ */
+ global $wpdb;
+
+ $deleted = $wpdb->delete( $wpdb->actionscheduler_actions, array( 'action_id' => $action_id ), array( '%d' ) );
+ if ( empty( $deleted ) ) {
+ /* translators: %s is the action ID */
+ throw new \InvalidArgumentException( sprintf( __( 'Unidentified action %s: we were unable to delete this action. It may may have been deleted by another process.', 'action-scheduler' ), $action_id ) );
+ }
+ do_action( 'action_scheduler_deleted_action', $action_id );
+ }
+
+ /**
+ * Get the schedule date for an action.
+ *
+ * @param string $action_id Action ID.
+ *
+ * @return \DateTime The local date the action is scheduled to run, or the date that it ran.
+ */
+ public function get_date( $action_id ) {
+ $date = $this->get_date_gmt( $action_id );
+ ActionScheduler_TimezoneHelper::set_local_timezone( $date );
+ return $date;
+ }
+
+ /**
+ * Get the GMT schedule date for an action.
+ *
+ * @param int $action_id Action ID.
+ *
+ * @throws \InvalidArgumentException If action cannot be identified.
+ * @return \DateTime The GMT date the action is scheduled to run, or the date that it ran.
+ */
+ protected function get_date_gmt( $action_id ) {
+ /**
+ * Global.
+ *
+ * @var \wpdb $wpdb
+ */
+ global $wpdb;
+
+ $record = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->actionscheduler_actions} WHERE action_id=%d", $action_id ) );
+ if ( empty( $record ) ) {
+ /* translators: %s is the action ID */
+ throw new \InvalidArgumentException( sprintf( __( 'Unidentified action %s: we were unable to determine the date of this action. It may may have been deleted by another process.', 'action-scheduler' ), $action_id ) );
+ }
+ if ( self::STATUS_PENDING === $record->status ) {
+ return as_get_datetime_object( $record->scheduled_date_gmt );
+ } else {
+ return as_get_datetime_object( $record->last_attempt_gmt );
+ }
+ }
+
+ /**
+ * Stake a claim on actions.
+ *
+ * @param int $max_actions Maximum number of action to include in claim.
+ * @param DateTime|null $before_date Jobs must be schedule before this date. Defaults to now.
+ * @param array $hooks Hooks to filter for.
+ * @param string $group Group to filter for.
+ *
+ * @return ActionScheduler_ActionClaim
+ */
+ public function stake_claim( $max_actions = 10, ?DateTime $before_date = null, $hooks = array(), $group = '' ) {
+ $claim_id = $this->generate_claim_id();
+
+ $this->claim_before_date = $before_date;
+ $this->claim_actions( $claim_id, $max_actions, $before_date, $hooks, $group );
+ $action_ids = $this->find_actions_by_claim_id( $claim_id );
+ $this->claim_before_date = null;
+
+ return new ActionScheduler_ActionClaim( $claim_id, $action_ids );
+ }
+
+ /**
+ * Generate a new action claim.
+ *
+ * @return int Claim ID.
+ */
+ protected function generate_claim_id() {
+ /**
+ * Global.
+ *
+ * @var \wpdb $wpdb
+ */
+ global $wpdb;
+
+ $now = as_get_datetime_object();
+ $wpdb->insert( $wpdb->actionscheduler_claims, array( 'date_created_gmt' => $now->format( 'Y-m-d H:i:s' ) ) );
+
+ return $wpdb->insert_id;
+ }
+
+ /**
+ * Set a claim filter.
+ *
+ * @param string $filter_name Claim filter name.
+ * @param mixed $filter_values Values to filter.
+ * @return void
+ */
+ public function set_claim_filter( $filter_name, $filter_values ) {
+ if ( isset( $this->claim_filters[ $filter_name ] ) ) {
+ $this->claim_filters[ $filter_name ] = $filter_values;
+ }
+ }
+
+ /**
+ * Get the claim filter value.
+ *
+ * @param string $filter_name Claim filter name.
+ * @return mixed
+ */
+ public function get_claim_filter( $filter_name ) {
+ if ( isset( $this->claim_filters[ $filter_name ] ) ) {
+ return $this->claim_filters[ $filter_name ];
+ }
+
+ return '';
+ }
+
+ /**
+ * Mark actions claimed.
+ *
+ * @param string $claim_id Claim Id.
+ * @param int $limit Number of action to include in claim.
+ * @param DateTime|null $before_date Should use UTC timezone.
+ * @param array $hooks Hooks to filter for.
+ * @param string $group Group to filter for.
+ *
+ * @return int The number of actions that were claimed.
+ * @throws \InvalidArgumentException Throws InvalidArgumentException if group doesn't exist.
+ * @throws \RuntimeException Throws RuntimeException if unable to claim action.
+ */
+ protected function claim_actions( $claim_id, $limit, ?DateTime $before_date = null, $hooks = array(), $group = '' ) {
+ /**
+ * Global.
+ *
+ * @var \wpdb $wpdb
+ */
+ global $wpdb;
+ $now = as_get_datetime_object();
+ $date = is_null( $before_date ) ? $now : clone $before_date;
+
+ // Set claim filters.
+ if ( ! empty( $hooks ) ) {
+ $this->set_claim_filter( 'hooks', $hooks );
+ } else {
+ $hooks = $this->get_claim_filter( 'hooks' );
+ }
+ if ( ! empty( $group ) ) {
+ $this->set_claim_filter( 'group', $group );
+ } else {
+ $group = $this->get_claim_filter( 'group' );
+ }
+
+ $where = 'WHERE claim_id = 0 AND scheduled_date_gmt <= %s AND status=%s';
+ $where_params = array(
+ $date->format( 'Y-m-d H:i:s' ),
+ self::STATUS_PENDING,
+ );
+
+ if ( ! empty( $hooks ) ) {
+ $placeholders = array_fill( 0, count( $hooks ), '%s' );
+ $where .= ' AND hook IN (' . join( ', ', $placeholders ) . ')';
+ $where_params = array_merge( $where_params, array_values( $hooks ) );
+ }
+
+ $group_operator = 'IN';
+ if ( empty( $group ) ) {
+ $group = $this->get_claim_filter( 'exclude-groups' );
+ $group_operator = 'NOT IN';
+ }
+
+ if ( ! empty( $group ) ) {
+ $group_ids = $this->get_group_ids( $group, false );
+
+ // throw exception if no matching group(s) found, this matches ActionScheduler_wpPostStore's behaviour.
+ if ( empty( $group_ids ) ) {
+ throw new InvalidArgumentException(
+ sprintf(
+ /* translators: %s: group name(s) */
+ _n(
+ 'The group "%s" does not exist.',
+ 'The groups "%s" do not exist.',
+ is_array( $group ) ? count( $group ) : 1,
+ 'action-scheduler'
+ ),
+ $group
+ )
+ );
+ }
+
+ $id_list = implode( ',', array_map( 'intval', $group_ids ) );
+ $where .= " AND group_id {$group_operator} ( $id_list )";
+ }
+
+ /**
+ * Sets the order-by clause used in the action claim query.
+ *
+ * @param string $order_by_sql
+ * @param string $claim_id Claim Id.
+ * @param array $hooks Hooks to filter for.
+ *
+ * @since 3.8.3 Made $claim_id and $hooks available.
+ * @since 3.4.0
+ */
+ $order = apply_filters( 'action_scheduler_claim_actions_order_by', 'ORDER BY priority ASC, attempts ASC, scheduled_date_gmt ASC, action_id ASC', $claim_id, $hooks );
+ $skip_locked = $this->db_supports_skip_locked() ? ' SKIP LOCKED' : '';
+
+ // Selecting the action_ids that we plan to claim, while skipping any locked rows to avoid deadlocking.
+ $select_sql = $wpdb->prepare( "SELECT action_id from {$wpdb->actionscheduler_actions} {$where} {$order} LIMIT %d FOR UPDATE{$skip_locked}", array_merge( $where_params, array( $limit ) ) );
+
+ // Now place it into an UPDATE statement by joining the result sets, allowing for the SKIP LOCKED behavior to take effect.
+ $update_sql = "UPDATE {$wpdb->actionscheduler_actions} t1 JOIN ( $select_sql ) t2 ON t1.action_id = t2.action_id SET claim_id=%d, last_attempt_gmt=%s, last_attempt_local=%s";
+ $update_params = array(
+ $claim_id,
+ $now->format( 'Y-m-d H:i:s' ),
+ current_time( 'mysql' ),
+ );
+
+ $rows_affected = $wpdb->query( $wpdb->prepare( $update_sql, $update_params ) );
+ if ( false === $rows_affected ) {
+ $error = empty( $wpdb->last_error )
+ ? _x( 'unknown', 'database error', 'action-scheduler' )
+ : $wpdb->last_error;
+ throw new \RuntimeException(
+ sprintf(
+ /* translators: %s database error. */
+ __( 'Unable to claim actions. Database error: %s.', 'action-scheduler' ),
+ $error
+ )
+ );
+ }
+
+ return (int) $rows_affected;
+ }
+
+ /**
+ * Determines whether the database supports using SKIP LOCKED. This logic mimicks the $wpdb::has_cap() logic.
+ *
+ * SKIP_LOCKED support was added to MariaDB in 10.6.0 and to MySQL in 8.0.1
+ *
+ * @return bool
+ */
+ private function db_supports_skip_locked() {
+ global $wpdb;
+ $db_version = $wpdb->db_version();
+ $db_server_info = $wpdb->db_server_info();
+ $is_mariadb = ( false !== strpos( $db_server_info, 'MariaDB' ) );
+
+ if ( $is_mariadb &&
+ '5.5.5' === $db_version &&
+ PHP_VERSION_ID < 80016 // PHP 8.0.15 or older.
+ ) {
+ /*
+ * Account for MariaDB version being prefixed with '5.5.5-' on older PHP versions.
+ */
+ $db_server_info = preg_replace( '/^5\.5\.5-(.*)/', '$1', $db_server_info );
+ $db_version = preg_replace( '/[^0-9.].*/', '', $db_server_info );
+ }
+
+ $is_supported = ( $is_mariadb && version_compare( $db_version, '10.6.0', '>=' ) ) ||
+ ( ! $is_mariadb && version_compare( $db_version, '8.0.1', '>=' ) );
+
+ /**
+ * Filter whether the database supports the SKIP LOCKED modifier for queries.
+ *
+ * @param bool $is_supported Whether SKIP LOCKED is supported.
+ *
+ * @since 3.9.3
+ */
+ return apply_filters( 'action_scheduler_db_supports_skip_locked', $is_supported );
+ }
+
+ /**
+ * Get the number of active claims.
+ *
+ * @return int
+ */
+ public function get_claim_count() {
+ global $wpdb;
+
+ $sql = "SELECT COUNT(DISTINCT claim_id) FROM {$wpdb->actionscheduler_actions} WHERE claim_id != 0 AND status IN ( %s, %s)";
+ $sql = $wpdb->prepare( $sql, array( self::STATUS_PENDING, self::STATUS_RUNNING ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
+
+ return (int) $wpdb->get_var( $sql ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
+ }
+
+ /**
+ * Return an action's claim ID, as stored in the claim_id column.
+ *
+ * @param string $action_id Action ID.
+ * @return mixed
+ */
+ public function get_claim_id( $action_id ) {
+ /**
+ * Global.
+ *
+ * @var \wpdb $wpdb
+ */
+ global $wpdb;
+
+ $sql = "SELECT claim_id FROM {$wpdb->actionscheduler_actions} WHERE action_id=%d";
+ $sql = $wpdb->prepare( $sql, $action_id ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
+
+ return (int) $wpdb->get_var( $sql ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
+ }
+
+ /**
+ * Retrieve the action IDs of action in a claim.
+ *
+ * @param int $claim_id Claim ID.
+ * @return int[]
+ */
+ public function find_actions_by_claim_id( $claim_id ) {
+ /**
+ * Global.
+ *
+ * @var \wpdb $wpdb
+ */
+ global $wpdb;
+
+ $action_ids = array();
+ $before_date = isset( $this->claim_before_date ) ? $this->claim_before_date : as_get_datetime_object();
+ $cut_off = $before_date->format( 'Y-m-d H:i:s' );
+
+ $sql = $wpdb->prepare(
+ "SELECT action_id, scheduled_date_gmt FROM {$wpdb->actionscheduler_actions} WHERE claim_id = %d ORDER BY priority ASC, attempts ASC, scheduled_date_gmt ASC, action_id ASC",
+ $claim_id
+ );
+
+ // Verify that the scheduled date for each action is within the expected bounds (in some unusual
+ // cases, we cannot depend on MySQL to honor all of the WHERE conditions we specify).
+ foreach ( $wpdb->get_results( $sql ) as $claimed_action ) { // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
+ if ( $claimed_action->scheduled_date_gmt <= $cut_off ) {
+ $action_ids[] = absint( $claimed_action->action_id );
+ }
+ }
+
+ return $action_ids;
+ }
+
+ /**
+ * Release pending actions from a claim and delete the claim.
+ *
+ * @param ActionScheduler_ActionClaim $claim Claim object.
+ * @throws \RuntimeException When unable to release actions from claim.
+ */
+ public function release_claim( ActionScheduler_ActionClaim $claim ) {
+ /**
+ * Global.
+ *
+ * @var \wpdb $wpdb
+ */
+ global $wpdb;
+
+ if ( 0 === intval( $claim->get_id() ) ) {
+ // Verify that the claim_id is valid before attempting to release it.
+ return;
+ }
+
+ /**
+ * Deadlock warning: This function modifies actions to release them from claims that have been processed. Earlier, we used to it in a atomic query, i.e. we would update all actions belonging to a particular claim_id with claim_id = 0.
+ * While this was functionally correct, it would cause deadlock, since this update query will hold a lock on the claim_id_.. index on the action table.
+ * This allowed the possibility of a race condition, where the claimer query is also running at the same time, then the claimer query will also try to acquire a lock on the claim_id_.. index, and in this case if claim release query has already progressed to the point of acquiring the lock, but have not updated yet, it would cause a deadlock.
+ *
+ * We resolve this by getting all the actions_id that we want to release claim from in a separate query, and then releasing the claim on each of them. This way, our lock is acquired on the action_id index instead of the claim_id index. Note that the lock on claim_id will still be acquired, but it will only when we actually make the update, rather than when we select the actions.
+ *
+ * We only release pending actions in order for them to be claimed by another process.
+ */
+ $action_ids = $wpdb->get_col( $wpdb->prepare( "SELECT action_id FROM {$wpdb->actionscheduler_actions} WHERE claim_id = %d AND status = %s", $claim->get_id(), self::STATUS_PENDING ) );
+
+ $row_updates = 0;
+ if ( count( $action_ids ) > 0 ) {
+ $action_id_string = implode( ',', array_map( 'absint', $action_ids ) );
+ $row_updates = $wpdb->query( "UPDATE {$wpdb->actionscheduler_actions} SET claim_id = 0 WHERE action_id IN ({$action_id_string})" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
+ }
+
+ $wpdb->delete( $wpdb->actionscheduler_claims, array( 'claim_id' => $claim->get_id() ), array( '%d' ) );
+
+ if ( $row_updates < count( $action_ids ) ) {
+ throw new RuntimeException(
+ sprintf(
+ // translators: %d is an id.
+ __( 'Unable to release actions from claim id %d.', 'action-scheduler' ),
+ $claim->get_id()
+ )
+ );
+ }
+ }
+
+ /**
+ * Remove the claim from an action.
+ *
+ * @param int $action_id Action ID.
+ *
+ * @return void
+ */
+ public function unclaim_action( $action_id ) {
+ /**
+ * Global.
+ *
+ * @var \wpdb $wpdb
+ */
+ global $wpdb;
+
+ $wpdb->update(
+ $wpdb->actionscheduler_actions,
+ array( 'claim_id' => 0 ),
+ array( 'action_id' => $action_id ),
+ array( '%s' ),
+ array( '%d' )
+ );
+ }
+
+ /**
+ * Mark an action as failed.
+ *
+ * @param int $action_id Action ID.
+ * @throws \InvalidArgumentException Throw an exception if action was not updated.
+ */
+ public function mark_failure( $action_id ) {
+ /**
+ * Global.
+
+ * @var \wpdb $wpdb
+ */
+ global $wpdb;
+
+ $updated = $wpdb->update(
+ $wpdb->actionscheduler_actions,
+ array( 'status' => self::STATUS_FAILED ),
+ array( 'action_id' => $action_id ),
+ array( '%s' ),
+ array( '%d' )
+ );
+ if ( empty( $updated ) ) {
+ /* translators: %s is the action ID */
+ throw new \InvalidArgumentException( sprintf( __( 'Unidentified action %s: we were unable to mark this action as having failed. It may may have been deleted by another process.', 'action-scheduler' ), $action_id ) );
+ }
+ }
+
+ /**
+ * Add execution message to action log.
+ *
+ * @throws Exception If the action status cannot be updated to self::STATUS_RUNNING ('in-progress').
+ *
+ * @param int $action_id Action ID.
+ *
+ * @return void
+ */
+ public function log_execution( $action_id ) {
+ /**
+ * Global.
+ *
+ * @var \wpdb $wpdb
+ */
+ global $wpdb;
+
+ $sql = "UPDATE {$wpdb->actionscheduler_actions} SET attempts = attempts+1, status=%s, last_attempt_gmt = %s, last_attempt_local = %s WHERE action_id = %d";
+ $sql = $wpdb->prepare( $sql, self::STATUS_RUNNING, current_time( 'mysql', true ), current_time( 'mysql' ), $action_id ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
+
+ // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
+ $status_updated = $wpdb->query( $sql );
+
+ if ( ! $status_updated ) {
+ throw new Exception(
+ sprintf(
+ /* translators: 1: action ID. 2: status slug. */
+ __( 'Unable to update the status of action %1$d to %2$s.', 'action-scheduler' ),
+ $action_id,
+ self::STATUS_RUNNING
+ )
+ );
+ }
+ }
+
+ /**
+ * Mark an action as complete.
+ *
+ * @param int $action_id Action ID.
+ *
+ * @return void
+ * @throws \InvalidArgumentException Throw an exception if action was not updated.
+ */
+ public function mark_complete( $action_id ) {
+ /**
+ * Global.
+ *
+ * @var \wpdb $wpdb
+ */
+ global $wpdb;
+
+ $updated = $wpdb->update(
+ $wpdb->actionscheduler_actions,
+ array(
+ 'status' => self::STATUS_COMPLETE,
+ 'last_attempt_gmt' => current_time( 'mysql', true ),
+ 'last_attempt_local' => current_time( 'mysql' ),
+ ),
+ array( 'action_id' => $action_id ),
+ array( '%s' ),
+ array( '%d' )
+ );
+ if ( empty( $updated ) ) {
+ /* translators: %s is the action ID */
+ throw new \InvalidArgumentException( sprintf( __( 'Unidentified action %s: we were unable to mark this action as having completed. It may may have been deleted by another process.', 'action-scheduler' ), $action_id ) );
+ }
+
+ /**
+ * Fires after a scheduled action has been completed.
+ *
+ * @since 3.4.2
+ *
+ * @param int $action_id Action ID.
+ */
+ do_action( 'action_scheduler_completed_action', $action_id );
+ }
+
+ /**
+ * Get an action's status.
+ *
+ * @param int $action_id Action ID.
+ *
+ * @return string
+ * @throws \InvalidArgumentException Throw an exception if not status was found for action_id.
+ * @throws \RuntimeException Throw an exception if action status could not be retrieved.
+ */
+ public function get_status( $action_id ) {
+ /**
+ * Global.
+ *
+ * @var \wpdb $wpdb
+ */
+ global $wpdb;
+
+ $sql = "SELECT status FROM {$wpdb->actionscheduler_actions} WHERE action_id=%d";
+ $sql = $wpdb->prepare( $sql, $action_id ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
+ $status = $wpdb->get_var( $sql ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
+
+ if ( is_null( $status ) ) {
+ throw new \InvalidArgumentException( __( 'Invalid action ID. No status found.', 'action-scheduler' ) );
+ } elseif ( empty( $status ) ) {
+ throw new \RuntimeException( __( 'Unknown status found for action.', 'action-scheduler' ) );
+ } else {
+ return $status;
+ }
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_HybridStore.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_HybridStore.php
new file mode 100755
index 00000000..40520cc8
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_HybridStore.php
@@ -0,0 +1,460 @@
+demarkation_id = (int) get_option( self::DEMARKATION_OPTION, 0 );
+ if ( empty( $config ) ) {
+ $config = Controller::instance()->get_migration_config_object();
+ }
+ $this->primary_store = $config->get_destination_store();
+ $this->secondary_store = $config->get_source_store();
+ $this->migration_runner = new Runner( $config );
+ }
+
+ /**
+ * Initialize the table data store tables.
+ *
+ * @codeCoverageIgnore
+ */
+ public function init() {
+ add_action( 'action_scheduler/created_table', array( $this, 'set_autoincrement' ), 10, 2 );
+ $this->primary_store->init();
+ $this->secondary_store->init();
+ remove_action( 'action_scheduler/created_table', array( $this, 'set_autoincrement' ), 10 );
+ }
+
+ /**
+ * When the actions table is created, set its autoincrement
+ * value to be one higher than the posts table to ensure that
+ * there are no ID collisions.
+ *
+ * @param string $table_name Table name.
+ * @param string $table_suffix Suffix of table name.
+ *
+ * @return void
+ * @codeCoverageIgnore
+ */
+ public function set_autoincrement( $table_name, $table_suffix ) {
+ if ( ActionScheduler_StoreSchema::ACTIONS_TABLE === $table_suffix ) {
+ if ( empty( $this->demarkation_id ) ) {
+ $this->demarkation_id = $this->set_demarkation_id();
+ }
+
+ /**
+ * Global.
+ *
+ * @var \wpdb $wpdb
+ */
+ global $wpdb;
+
+ /**
+ * A default date of '0000-00-00 00:00:00' is invalid in MySQL 5.7 when configured with
+ * sql_mode including both STRICT_TRANS_TABLES and NO_ZERO_DATE.
+ */
+ $default_date = new DateTime( 'tomorrow' );
+ $null_action = new ActionScheduler_NullAction();
+ $date_gmt = $this->get_scheduled_date_string( $null_action, $default_date );
+ $date_local = $this->get_scheduled_date_string_local( $null_action, $default_date );
+
+ $row_count = $wpdb->insert(
+ $wpdb->{ActionScheduler_StoreSchema::ACTIONS_TABLE},
+ array(
+ 'action_id' => $this->demarkation_id,
+ 'hook' => '',
+ 'status' => '',
+ 'scheduled_date_gmt' => $date_gmt,
+ 'scheduled_date_local' => $date_local,
+ 'last_attempt_gmt' => $date_gmt,
+ 'last_attempt_local' => $date_local,
+ )
+ );
+ if ( $row_count > 0 ) {
+ $wpdb->delete(
+ $wpdb->{ActionScheduler_StoreSchema::ACTIONS_TABLE},
+ array( 'action_id' => $this->demarkation_id )
+ );
+ }
+ }
+ }
+
+ /**
+ * Store the demarkation id in WP options.
+ *
+ * @param int $id The ID to set as the demarkation point between the two stores
+ * Leave null to use the next ID from the WP posts table.
+ *
+ * @return int The new ID.
+ *
+ * @codeCoverageIgnore
+ */
+ private function set_demarkation_id( $id = null ) {
+ if ( empty( $id ) ) {
+ /**
+ * Global.
+ *
+ * @var \wpdb $wpdb
+ */
+ global $wpdb;
+
+ $id = (int) $wpdb->get_var( "SELECT MAX(ID) FROM $wpdb->posts" );
+ $id++;
+ }
+ update_option( self::DEMARKATION_OPTION, $id );
+
+ return $id;
+ }
+
+ /**
+ * Find the first matching action from the secondary store.
+ * If it exists, migrate it to the primary store immediately.
+ * After it migrates, the secondary store will logically contain
+ * the next matching action, so return the result thence.
+ *
+ * @param string $hook Action's hook.
+ * @param array $params Action's arguments.
+ *
+ * @return string
+ */
+ public function find_action( $hook, $params = array() ) {
+ $found_unmigrated_action = $this->secondary_store->find_action( $hook, $params );
+ if ( ! empty( $found_unmigrated_action ) ) {
+ $this->migrate( array( $found_unmigrated_action ) );
+ }
+
+ return $this->primary_store->find_action( $hook, $params );
+ }
+
+ /**
+ * Find actions matching the query in the secondary source first.
+ * If any are found, migrate them immediately. Then the secondary
+ * store will contain the canonical results.
+ *
+ * @param array $query Query arguments.
+ * @param string $query_type Whether to select or count the results. Default, select.
+ *
+ * @return int[]
+ */
+ public function query_actions( $query = array(), $query_type = 'select' ) {
+ $found_unmigrated_actions = $this->secondary_store->query_actions( $query, 'select' );
+ if ( ! empty( $found_unmigrated_actions ) ) {
+ $this->migrate( $found_unmigrated_actions );
+ }
+
+ return $this->primary_store->query_actions( $query, $query_type );
+ }
+
+ /**
+ * Get a count of all actions in the store, grouped by status
+ *
+ * @return array Set of 'status' => int $count pairs for statuses with 1 or more actions of that status.
+ */
+ public function action_counts() {
+ $unmigrated_actions_count = $this->secondary_store->action_counts();
+ $migrated_actions_count = $this->primary_store->action_counts();
+ $actions_count_by_status = array();
+
+ foreach ( $this->get_status_labels() as $status_key => $status_label ) {
+
+ $count = 0;
+
+ if ( isset( $unmigrated_actions_count[ $status_key ] ) ) {
+ $count += $unmigrated_actions_count[ $status_key ];
+ }
+
+ if ( isset( $migrated_actions_count[ $status_key ] ) ) {
+ $count += $migrated_actions_count[ $status_key ];
+ }
+
+ $actions_count_by_status[ $status_key ] = $count;
+ }
+
+ $actions_count_by_status = array_filter( $actions_count_by_status );
+
+ return $actions_count_by_status;
+ }
+
+ /**
+ * If any actions would have been claimed by the secondary store,
+ * migrate them immediately, then ask the primary store for the
+ * canonical claim.
+ *
+ * @param int $max_actions Maximum number of actions to claim.
+ * @param null|DateTime $before_date Latest timestamp of actions to claim.
+ * @param string[] $hooks Hook of actions to claim.
+ * @param string $group Group of actions to claim.
+ *
+ * @return ActionScheduler_ActionClaim
+ */
+ public function stake_claim( $max_actions = 10, ?DateTime $before_date = null, $hooks = array(), $group = '' ) {
+ $claim = $this->secondary_store->stake_claim( $max_actions, $before_date, $hooks, $group );
+
+ $claimed_actions = $claim->get_actions();
+ if ( ! empty( $claimed_actions ) ) {
+ $this->migrate( $claimed_actions );
+ }
+
+ $this->secondary_store->release_claim( $claim );
+
+ return $this->primary_store->stake_claim( $max_actions, $before_date, $hooks, $group );
+ }
+
+ /**
+ * Migrate a list of actions to the table data store.
+ *
+ * @param array $action_ids List of action IDs.
+ */
+ private function migrate( $action_ids ) {
+ $this->migration_runner->migrate_actions( $action_ids );
+ }
+
+ /**
+ * Save an action to the primary store.
+ *
+ * @param ActionScheduler_Action $action Action object to be saved.
+ * @param DateTime|null $date Optional. Schedule date. Default null.
+ *
+ * @return int The action ID
+ */
+ public function save_action( ActionScheduler_Action $action, ?DateTime $date = null ) {
+ return $this->primary_store->save_action( $action, $date );
+ }
+
+ /**
+ * Retrieve an existing action whether migrated or not.
+ *
+ * @param int $action_id Action ID.
+ */
+ public function fetch_action( $action_id ) {
+ $store = $this->get_store_from_action_id( $action_id, true );
+ if ( $store ) {
+ return $store->fetch_action( $action_id );
+ } else {
+ return new ActionScheduler_NullAction();
+ }
+ }
+
+ /**
+ * Cancel an existing action whether migrated or not.
+ *
+ * @param int $action_id Action ID.
+ */
+ public function cancel_action( $action_id ) {
+ $store = $this->get_store_from_action_id( $action_id );
+ if ( $store ) {
+ $store->cancel_action( $action_id );
+ }
+ }
+
+ /**
+ * Delete an existing action whether migrated or not.
+ *
+ * @param int $action_id Action ID.
+ */
+ public function delete_action( $action_id ) {
+ $store = $this->get_store_from_action_id( $action_id );
+ if ( $store ) {
+ $store->delete_action( $action_id );
+ }
+ }
+
+ /**
+ * Get the schedule date an existing action whether migrated or not.
+ *
+ * @param int $action_id Action ID.
+ */
+ public function get_date( $action_id ) {
+ $store = $this->get_store_from_action_id( $action_id );
+ if ( $store ) {
+ return $store->get_date( $action_id );
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Mark an existing action as failed whether migrated or not.
+ *
+ * @param int $action_id Action ID.
+ */
+ public function mark_failure( $action_id ) {
+ $store = $this->get_store_from_action_id( $action_id );
+ if ( $store ) {
+ $store->mark_failure( $action_id );
+ }
+ }
+
+ /**
+ * Log the execution of an existing action whether migrated or not.
+ *
+ * @param int $action_id Action ID.
+ */
+ public function log_execution( $action_id ) {
+ $store = $this->get_store_from_action_id( $action_id );
+ if ( $store ) {
+ $store->log_execution( $action_id );
+ }
+ }
+
+ /**
+ * Mark an existing action complete whether migrated or not.
+ *
+ * @param int $action_id Action ID.
+ */
+ public function mark_complete( $action_id ) {
+ $store = $this->get_store_from_action_id( $action_id );
+ if ( $store ) {
+ $store->mark_complete( $action_id );
+ }
+ }
+
+ /**
+ * Get an existing action status whether migrated or not.
+ *
+ * @param int $action_id Action ID.
+ */
+ public function get_status( $action_id ) {
+ $store = $this->get_store_from_action_id( $action_id );
+ if ( $store ) {
+ return $store->get_status( $action_id );
+ }
+ return null;
+ }
+
+ /**
+ * Return which store an action is stored in.
+ *
+ * @param int $action_id ID of the action.
+ * @param bool $primary_first Optional flag indicating search the primary store first.
+ * @return ActionScheduler_Store
+ */
+ protected function get_store_from_action_id( $action_id, $primary_first = false ) {
+ if ( $primary_first ) {
+ $stores = array(
+ $this->primary_store,
+ $this->secondary_store,
+ );
+ } elseif ( $action_id < $this->demarkation_id ) {
+ $stores = array(
+ $this->secondary_store,
+ $this->primary_store,
+ );
+ } else {
+ $stores = array(
+ $this->primary_store,
+ );
+ }
+
+ foreach ( $stores as $store ) {
+ $action = $store->fetch_action( $action_id );
+ if ( ! is_a( $action, 'ActionScheduler_NullAction' ) ) {
+ return $store;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * All claim-related functions should operate solely
+ * on the primary store.
+ * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
+
+ /**
+ * Get the claim count from the table data store.
+ */
+ public function get_claim_count() {
+ return $this->primary_store->get_claim_count();
+ }
+
+ /**
+ * Retrieve the claim ID for an action from the table data store.
+ *
+ * @param int $action_id Action ID.
+ */
+ public function get_claim_id( $action_id ) {
+ return $this->primary_store->get_claim_id( $action_id );
+ }
+
+ /**
+ * Release a claim in the table data store on any pending actions.
+ *
+ * @param ActionScheduler_ActionClaim $claim Claim object.
+ */
+ public function release_claim( ActionScheduler_ActionClaim $claim ) {
+ $this->primary_store->release_claim( $claim );
+ }
+
+ /**
+ * Release claims on an action in the table data store.
+ *
+ * @param int $action_id Action ID.
+ */
+ public function unclaim_action( $action_id ) {
+ $this->primary_store->unclaim_action( $action_id );
+ }
+
+ /**
+ * Retrieve a list of action IDs by claim.
+ *
+ * @param int $claim_id Claim ID.
+ */
+ public function find_actions_by_claim_id( $claim_id ) {
+ return $this->primary_store->find_actions_by_claim_id( $claim_id );
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpCommentLogger.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpCommentLogger.php
new file mode 100755
index 00000000..a9d84d31
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpCommentLogger.php
@@ -0,0 +1,282 @@
+create_wp_comment( $action_id, $message, $date );
+ return $comment_id;
+ }
+
+ /**
+ * Create comment.
+ *
+ * @param int $action_id Action ID.
+ * @param string $message Action log's message.
+ * @param DateTime $date Action log entry's timestamp.
+ */
+ protected function create_wp_comment( $action_id, $message, DateTime $date ) {
+
+ $comment_date_gmt = $date->format( 'Y-m-d H:i:s' );
+ ActionScheduler_TimezoneHelper::set_local_timezone( $date );
+ $comment_data = array(
+ 'comment_post_ID' => $action_id,
+ 'comment_date' => $date->format( 'Y-m-d H:i:s' ),
+ 'comment_date_gmt' => $comment_date_gmt,
+ 'comment_author' => self::AGENT,
+ 'comment_content' => $message,
+ 'comment_agent' => self::AGENT,
+ 'comment_type' => self::TYPE,
+ );
+
+ return wp_insert_comment( $comment_data );
+ }
+
+ /**
+ * Get single log entry for action.
+ *
+ * @param string $entry_id Entry ID.
+ *
+ * @return ActionScheduler_LogEntry
+ */
+ public function get_entry( $entry_id ) {
+ $comment = $this->get_comment( $entry_id );
+
+ if ( empty( $comment ) || self::TYPE !== $comment->comment_type ) {
+ return new ActionScheduler_NullLogEntry();
+ }
+
+ $date = as_get_datetime_object( $comment->comment_date_gmt );
+ ActionScheduler_TimezoneHelper::set_local_timezone( $date );
+ return new ActionScheduler_LogEntry( $comment->comment_post_ID, $comment->comment_content, $date );
+ }
+
+ /**
+ * Get action's logs.
+ *
+ * @param string $action_id Action ID.
+ *
+ * @return ActionScheduler_LogEntry[]
+ */
+ public function get_logs( $action_id ) {
+ $status = 'all';
+ $logs = array();
+
+ if ( get_post_status( $action_id ) === 'trash' ) {
+ $status = 'post-trashed';
+ }
+
+ $comments = get_comments(
+ array(
+ 'post_id' => $action_id,
+ 'orderby' => 'comment_date_gmt',
+ 'order' => 'ASC',
+ 'type' => self::TYPE,
+ 'status' => $status,
+ )
+ );
+
+ foreach ( $comments as $c ) {
+ $entry = $this->get_entry( $c );
+
+ if ( ! empty( $entry ) ) {
+ $logs[] = $entry;
+ }
+ }
+
+ return $logs;
+ }
+
+ /**
+ * Get comment.
+ *
+ * @param int $comment_id Comment ID.
+ */
+ protected function get_comment( $comment_id ) {
+ return get_comment( $comment_id );
+ }
+
+ /**
+ * Filter comment queries.
+ *
+ * @param WP_Comment_Query $query Comment query object.
+ */
+ public function filter_comment_queries( $query ) {
+ foreach ( array( 'ID', 'parent', 'post_author', 'post_name', 'post_parent', 'type', 'post_type', 'post_id', 'post_ID' ) as $key ) {
+ if ( ! empty( $query->query_vars[ $key ] ) ) {
+ return; // don't slow down queries that wouldn't include action_log comments anyway.
+ }
+ }
+ $query->query_vars['action_log_filter'] = true;
+ add_filter( 'comments_clauses', array( $this, 'filter_comment_query_clauses' ), 10, 2 );
+ }
+
+ /**
+ * Filter comment queries.
+ *
+ * @param array $clauses Query's clauses.
+ * @param WP_Comment_Query $query Query object.
+ *
+ * @return array
+ */
+ public function filter_comment_query_clauses( $clauses, $query ) {
+ if ( ! empty( $query->query_vars['action_log_filter'] ) ) {
+ $clauses['where'] .= $this->get_where_clause();
+ }
+ return $clauses;
+ }
+
+ /**
+ * Make sure Action Scheduler logs are excluded from comment feeds, which use WP_Query, not
+ * the WP_Comment_Query class handled by @see self::filter_comment_queries().
+ *
+ * @param string $where Query's `where` clause.
+ * @param WP_Query $query Query object.
+ *
+ * @return string
+ */
+ public function filter_comment_feed( $where, $query ) {
+ if ( is_comment_feed() ) {
+ $where .= $this->get_where_clause();
+ }
+ return $where;
+ }
+
+ /**
+ * Return a SQL clause to exclude Action Scheduler comments.
+ *
+ * @return string
+ */
+ protected function get_where_clause() {
+ global $wpdb;
+ return sprintf( " AND {$wpdb->comments}.comment_type != '%s'", self::TYPE );
+ }
+
+ /**
+ * Remove action log entries from wp_count_comments()
+ *
+ * @param array $stats Comment count.
+ * @param int $post_id Post ID.
+ *
+ * @return object
+ */
+ public function filter_comment_count( $stats, $post_id ) {
+ global $wpdb;
+
+ if ( 0 === $post_id ) {
+ $stats = $this->get_comment_count();
+ }
+
+ return $stats;
+ }
+
+ /**
+ * Retrieve the comment counts from our cache, or the database if the cached version isn't set.
+ *
+ * @return object
+ */
+ protected function get_comment_count() {
+ global $wpdb;
+
+ $stats = get_transient( 'as_comment_count' );
+
+ if ( ! $stats ) {
+ $stats = array();
+ $count = $wpdb->get_results( "SELECT comment_approved, COUNT( * ) AS num_comments FROM {$wpdb->comments} WHERE comment_type NOT IN('order_note','action_log') GROUP BY comment_approved", ARRAY_A );
+ $total = 0;
+ $stats = array();
+ $approved = array(
+ '0' => 'moderated',
+ '1' => 'approved',
+ 'spam' => 'spam',
+ 'trash' => 'trash',
+ 'post-trashed' => 'post-trashed',
+ );
+
+ foreach ( (array) $count as $row ) {
+ // Don't count post-trashed toward totals.
+ if ( 'post-trashed' !== $row['comment_approved'] && 'trash' !== $row['comment_approved'] ) {
+ $total += $row['num_comments'];
+ }
+ if ( isset( $approved[ $row['comment_approved'] ] ) ) {
+ $stats[ $approved[ $row['comment_approved'] ] ] = $row['num_comments'];
+ }
+ }
+
+ $stats['total_comments'] = $total;
+ $stats['all'] = $total;
+
+ foreach ( $approved as $key ) {
+ if ( empty( $stats[ $key ] ) ) {
+ $stats[ $key ] = 0;
+ }
+ }
+
+ $stats = (object) $stats;
+ set_transient( 'as_comment_count', $stats );
+ }
+
+ return $stats;
+ }
+
+ /**
+ * Delete comment count cache whenever there is new comment or the status of a comment changes. Cache
+ * will be regenerated next time ActionScheduler_wpCommentLogger::filter_comment_count() is called.
+ */
+ public function delete_comment_count_cache() {
+ delete_transient( 'as_comment_count' );
+ }
+
+ /**
+ * Initialize.
+ *
+ * @codeCoverageIgnore
+ */
+ public function init() {
+ add_action( 'action_scheduler_before_process_queue', array( $this, 'disable_comment_counting' ), 10, 0 );
+ add_action( 'action_scheduler_after_process_queue', array( $this, 'enable_comment_counting' ), 10, 0 );
+
+ parent::init();
+
+ add_action( 'pre_get_comments', array( $this, 'filter_comment_queries' ), 10, 1 );
+ add_action( 'wp_count_comments', array( $this, 'filter_comment_count' ), 20, 2 ); // run after WC_Comments::wp_count_comments() to make sure we exclude order notes and action logs.
+ add_action( 'comment_feed_where', array( $this, 'filter_comment_feed' ), 10, 2 );
+
+ // Delete comments count cache whenever there is a new comment or a comment status changes.
+ add_action( 'wp_insert_comment', array( $this, 'delete_comment_count_cache' ) );
+ add_action( 'wp_set_comment_status', array( $this, 'delete_comment_count_cache' ) );
+ }
+
+ /**
+ * Defer comment counting.
+ */
+ public function disable_comment_counting() {
+ wp_defer_comment_counting( true );
+ }
+
+ /**
+ * Enable comment counting.
+ */
+ public function enable_comment_counting() {
+ wp_defer_comment_counting( false );
+ }
+
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore.php
new file mode 100755
index 00000000..8f6375a6
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore.php
@@ -0,0 +1,1105 @@
+validate_action( $action );
+ $post_array = $this->create_post_array( $action, $scheduled_date );
+ $post_id = $this->save_post_array( $post_array );
+ $this->save_post_schedule( $post_id, $action->get_schedule() );
+ $this->save_action_group( $post_id, $action->get_group() );
+ do_action( 'action_scheduler_stored_action', $post_id );
+ return $post_id;
+ } catch ( Exception $e ) {
+ /* translators: %s: action error message */
+ throw new RuntimeException( sprintf( __( 'Error saving action: %s', 'action-scheduler' ), $e->getMessage() ), 0 );
+ }
+ }
+
+ /**
+ * Create post array.
+ *
+ * @param ActionScheduler_Action $action Scheduled Action.
+ * @param DateTime|null $scheduled_date Scheduled Date.
+ *
+ * @return array Returns an array of post data.
+ */
+ protected function create_post_array( ActionScheduler_Action $action, ?DateTime $scheduled_date = null ) {
+ $post = array(
+ 'post_type' => self::POST_TYPE,
+ 'post_title' => $action->get_hook(),
+ 'post_content' => wp_json_encode( $action->get_args() ),
+ 'post_status' => ( $action->is_finished() ? 'publish' : 'pending' ),
+ 'post_date_gmt' => $this->get_scheduled_date_string( $action, $scheduled_date ),
+ 'post_date' => $this->get_scheduled_date_string_local( $action, $scheduled_date ),
+ );
+ return $post;
+ }
+
+ /**
+ * Save post array.
+ *
+ * @param array $post_array Post array.
+ * @return int Returns the post ID.
+ * @throws RuntimeException Throws an exception if the action could not be saved.
+ */
+ protected function save_post_array( $post_array ) {
+ add_filter( 'wp_insert_post_data', array( $this, 'filter_insert_post_data' ), 10, 1 );
+ add_filter( 'pre_wp_unique_post_slug', array( $this, 'set_unique_post_slug' ), 10, 5 );
+
+ $has_kses = false !== has_filter( 'content_save_pre', 'wp_filter_post_kses' );
+
+ if ( $has_kses ) {
+ // Prevent KSES from corrupting JSON in post_content.
+ kses_remove_filters();
+ }
+
+ $post_id = wp_insert_post( $post_array );
+
+ if ( $has_kses ) {
+ kses_init_filters();
+ }
+
+ remove_filter( 'wp_insert_post_data', array( $this, 'filter_insert_post_data' ), 10 );
+ remove_filter( 'pre_wp_unique_post_slug', array( $this, 'set_unique_post_slug' ), 10 );
+
+ if ( is_wp_error( $post_id ) || empty( $post_id ) ) {
+ throw new RuntimeException( __( 'Unable to save action.', 'action-scheduler' ) );
+ }
+ return $post_id;
+ }
+
+ /**
+ * Filter insert post data.
+ *
+ * @param array $postdata Post data to filter.
+ *
+ * @return array
+ */
+ public function filter_insert_post_data( $postdata ) {
+ if ( self::POST_TYPE === $postdata['post_type'] ) {
+ $postdata['post_author'] = 0;
+ if ( 'future' === $postdata['post_status'] ) {
+ $postdata['post_status'] = 'publish';
+ }
+ }
+ return $postdata;
+ }
+
+ /**
+ * Create a (probably unique) post name for scheduled actions in a more performant manner than wp_unique_post_slug().
+ *
+ * When an action's post status is transitioned to something other than 'draft', 'pending' or 'auto-draft, like 'publish'
+ * or 'failed' or 'trash', WordPress will find a unique slug (stored in post_name column) using the wp_unique_post_slug()
+ * function. This is done to ensure URL uniqueness. The approach taken by wp_unique_post_slug() is to iterate over existing
+ * post_name values that match, and append a number 1 greater than the largest. This makes sense when manually creating a
+ * post from the Edit Post screen. It becomes a bottleneck when automatically processing thousands of actions, with a
+ * database containing thousands of related post_name values.
+ *
+ * WordPress 5.1 introduces the 'pre_wp_unique_post_slug' filter for plugins to address this issue.
+ *
+ * We can short-circuit WordPress's wp_unique_post_slug() approach using the 'pre_wp_unique_post_slug' filter. This
+ * method is available to be used as a callback on that filter. It provides a more scalable approach to generating a
+ * post_name/slug that is probably unique. Because Action Scheduler never actually uses the post_name field, or an
+ * action's slug, being probably unique is good enough.
+ *
+ * For more backstory on this issue, see:
+ * - https://github.com/woocommerce/action-scheduler/issues/44 and
+ * - https://core.trac.wordpress.org/ticket/21112
+ *
+ * @param string $override_slug Short-circuit return value.
+ * @param string $slug The desired slug (post_name).
+ * @param int $post_ID Post ID.
+ * @param string $post_status The post status.
+ * @param string $post_type Post type.
+ * @return string
+ */
+ public function set_unique_post_slug( $override_slug, $slug, $post_ID, $post_status, $post_type ) {
+ if ( self::POST_TYPE === $post_type ) {
+ $override_slug = uniqid( self::POST_TYPE . '-', true ) . '-' . wp_generate_password( 32, false );
+ }
+ return $override_slug;
+ }
+
+ /**
+ * Save post schedule.
+ *
+ * @param int $post_id Post ID of the scheduled action.
+ * @param string $schedule Schedule to save.
+ *
+ * @return void
+ */
+ protected function save_post_schedule( $post_id, $schedule ) {
+ update_post_meta( $post_id, self::SCHEDULE_META_KEY, $schedule );
+ }
+
+ /**
+ * Save action group.
+ *
+ * @param int $post_id Post ID.
+ * @param string $group Group to save.
+ * @return void
+ */
+ protected function save_action_group( $post_id, $group ) {
+ if ( empty( $group ) ) {
+ wp_set_object_terms( $post_id, array(), self::GROUP_TAXONOMY, false );
+ } else {
+ wp_set_object_terms( $post_id, array( $group ), self::GROUP_TAXONOMY, false );
+ }
+ }
+
+ /**
+ * Fetch actions.
+ *
+ * @param int $action_id Action ID.
+ * @return object
+ */
+ public function fetch_action( $action_id ) {
+ $post = $this->get_post( $action_id );
+ if ( empty( $post ) || self::POST_TYPE !== $post->post_type ) {
+ return $this->get_null_action();
+ }
+
+ try {
+ $action = $this->make_action_from_post( $post );
+ } catch ( ActionScheduler_InvalidActionException $exception ) {
+ do_action( 'action_scheduler_failed_fetch_action', $post->ID, $exception );
+ return $this->get_null_action();
+ }
+
+ return $action;
+ }
+
+ /**
+ * Get post.
+ *
+ * @param string $action_id - Action ID.
+ * @return WP_Post|null
+ */
+ protected function get_post( $action_id ) {
+ if ( empty( $action_id ) ) {
+ return null;
+ }
+ return get_post( $action_id );
+ }
+
+ /**
+ * Get NULL action.
+ *
+ * @return ActionScheduler_NullAction
+ */
+ protected function get_null_action() {
+ return new ActionScheduler_NullAction();
+ }
+
+ /**
+ * Make action from post.
+ *
+ * @param WP_Post $post Post object.
+ * @return WP_Post
+ */
+ protected function make_action_from_post( $post ) {
+ $hook = $post->post_title;
+
+ $args = json_decode( $post->post_content, true );
+ $this->validate_args( $args, $post->ID );
+
+ $schedule = get_post_meta( $post->ID, self::SCHEDULE_META_KEY, true );
+ $this->validate_schedule( $schedule, $post->ID );
+
+ $group = wp_get_object_terms( $post->ID, self::GROUP_TAXONOMY, array( 'fields' => 'names' ) );
+ $group = empty( $group ) ? '' : reset( $group );
+
+ return ActionScheduler::factory()->get_stored_action( $this->get_action_status_by_post_status( $post->post_status ), $hook, $args, $schedule, $group );
+ }
+
+ /**
+ * Get action status by post status.
+ *
+ * @param string $post_status Post status.
+ *
+ * @throws InvalidArgumentException Throw InvalidArgumentException if $post_status not in known status fields returned by $this->get_status_labels().
+ * @return string
+ */
+ protected function get_action_status_by_post_status( $post_status ) {
+
+ switch ( $post_status ) {
+ case 'publish':
+ $action_status = self::STATUS_COMPLETE;
+ break;
+ case 'trash':
+ $action_status = self::STATUS_CANCELED;
+ break;
+ default:
+ if ( ! array_key_exists( $post_status, $this->get_status_labels() ) ) {
+ throw new InvalidArgumentException( sprintf( 'Invalid post status: "%s". No matching action status available.', $post_status ) );
+ }
+ $action_status = $post_status;
+ break;
+ }
+
+ return $action_status;
+ }
+
+ /**
+ * Get post status by action status.
+ *
+ * @param string $action_status Action status.
+ *
+ * @throws InvalidArgumentException Throws InvalidArgumentException if $post_status not in known status fields returned by $this->get_status_labels().
+ * @return string
+ */
+ protected function get_post_status_by_action_status( $action_status ) {
+
+ switch ( $action_status ) {
+ case self::STATUS_COMPLETE:
+ $post_status = 'publish';
+ break;
+ case self::STATUS_CANCELED:
+ $post_status = 'trash';
+ break;
+ default:
+ if ( ! array_key_exists( $action_status, $this->get_status_labels() ) ) {
+ throw new InvalidArgumentException( sprintf( 'Invalid action status: "%s".', $action_status ) );
+ }
+ $post_status = $action_status;
+ break;
+ }
+
+ return $post_status;
+ }
+
+ /**
+ * Returns the SQL statement to query (or count) actions.
+ *
+ * @param array $query - Filtering options.
+ * @param string $select_or_count - Whether the SQL should select and return the IDs or just the row count.
+ *
+ * @throws InvalidArgumentException - Throw InvalidArgumentException if $select_or_count not count or select.
+ * @return string SQL statement. The returned SQL is already properly escaped.
+ */
+ protected function get_query_actions_sql( array $query, $select_or_count = 'select' ) {
+
+ if ( ! in_array( $select_or_count, array( 'select', 'count' ), true ) ) {
+ throw new InvalidArgumentException( __( 'Invalid schedule. Cannot save action.', 'action-scheduler' ) );
+ }
+
+ $query = wp_parse_args(
+ $query,
+ array(
+ 'hook' => '',
+ 'args' => null,
+ 'date' => null,
+ 'date_compare' => '<=',
+ 'modified' => null,
+ 'modified_compare' => '<=',
+ 'group' => '',
+ 'status' => '',
+ 'claimed' => null,
+ 'per_page' => 5,
+ 'offset' => 0,
+ 'orderby' => 'date',
+ 'order' => 'ASC',
+ 'search' => '',
+ )
+ );
+
+ /**
+ * Global wpdb object.
+ *
+ * @var wpdb $wpdb
+ */
+ global $wpdb;
+ $sql = ( 'count' === $select_or_count ) ? 'SELECT count(p.ID)' : 'SELECT p.ID ';
+ $sql .= "FROM {$wpdb->posts} p";
+ $sql_params = array();
+ if ( empty( $query['group'] ) && 'group' === $query['orderby'] ) {
+ $sql .= " LEFT JOIN {$wpdb->term_relationships} tr ON tr.object_id=p.ID";
+ $sql .= " LEFT JOIN {$wpdb->term_taxonomy} tt ON tr.term_taxonomy_id=tt.term_taxonomy_id";
+ $sql .= " LEFT JOIN {$wpdb->terms} t ON tt.term_id=t.term_id";
+ } elseif ( ! empty( $query['group'] ) ) {
+ $sql .= " INNER JOIN {$wpdb->term_relationships} tr ON tr.object_id=p.ID";
+ $sql .= " INNER JOIN {$wpdb->term_taxonomy} tt ON tr.term_taxonomy_id=tt.term_taxonomy_id";
+ $sql .= " INNER JOIN {$wpdb->terms} t ON tt.term_id=t.term_id";
+ $sql .= ' AND t.slug=%s';
+ $sql_params[] = $query['group'];
+ }
+ $sql .= ' WHERE post_type=%s';
+ $sql_params[] = self::POST_TYPE;
+ if ( $query['hook'] ) {
+ $sql .= ' AND p.post_title=%s';
+ $sql_params[] = $query['hook'];
+ }
+ if ( ! is_null( $query['args'] ) ) {
+ $sql .= ' AND p.post_content=%s';
+ $sql_params[] = wp_json_encode( $query['args'] );
+ }
+
+ if ( $query['status'] ) {
+ $post_statuses = array_map( array( $this, 'get_post_status_by_action_status' ), (array) $query['status'] );
+ $placeholders = array_fill( 0, count( $post_statuses ), '%s' );
+ $sql .= ' AND p.post_status IN (' . join( ', ', $placeholders ) . ')';
+ $sql_params = array_merge( $sql_params, array_values( $post_statuses ) );
+ }
+
+ if ( $query['date'] instanceof DateTime ) {
+ $date = clone $query['date'];
+ $date->setTimezone( new DateTimeZone( 'UTC' ) );
+ $date_string = $date->format( 'Y-m-d H:i:s' );
+ $comparator = $this->validate_sql_comparator( $query['date_compare'] );
+ $sql .= " AND p.post_date_gmt $comparator %s";
+ $sql_params[] = $date_string;
+ }
+
+ if ( $query['modified'] instanceof DateTime ) {
+ $modified = clone $query['modified'];
+ $modified->setTimezone( new DateTimeZone( 'UTC' ) );
+ $date_string = $modified->format( 'Y-m-d H:i:s' );
+ $comparator = $this->validate_sql_comparator( $query['modified_compare'] );
+ $sql .= " AND p.post_modified_gmt $comparator %s";
+ $sql_params[] = $date_string;
+ }
+
+ if ( true === $query['claimed'] ) {
+ $sql .= " AND p.post_password != ''";
+ } elseif ( false === $query['claimed'] ) {
+ $sql .= " AND p.post_password = ''";
+ } elseif ( ! is_null( $query['claimed'] ) ) {
+ $sql .= ' AND p.post_password = %s';
+ $sql_params[] = $query['claimed'];
+ }
+
+ if ( ! empty( $query['search'] ) ) {
+ $sql .= ' AND (p.post_title LIKE %s OR p.post_content LIKE %s OR p.post_password LIKE %s)';
+ for ( $i = 0; $i < 3; $i++ ) {
+ $sql_params[] = sprintf( '%%%s%%', $query['search'] );
+ }
+ }
+
+ if ( 'select' === $select_or_count ) {
+ switch ( $query['orderby'] ) {
+ case 'hook':
+ $orderby = 'p.post_title';
+ break;
+ case 'group':
+ $orderby = 't.name';
+ break;
+ case 'status':
+ $orderby = 'p.post_status';
+ break;
+ case 'modified':
+ $orderby = 'p.post_modified';
+ break;
+ case 'claim_id':
+ $orderby = 'p.post_password';
+ break;
+ case 'schedule':
+ case 'date':
+ default:
+ $orderby = 'p.post_date_gmt';
+ break;
+ }
+ if ( 'ASC' === strtoupper( $query['order'] ) ) {
+ $order = 'ASC';
+ } else {
+ $order = 'DESC';
+ }
+ $sql .= " ORDER BY $orderby $order";
+ if ( $query['per_page'] > 0 ) {
+ $sql .= ' LIMIT %d, %d';
+ $sql_params[] = $query['offset'];
+ $sql_params[] = $query['per_page'];
+ }
+ }
+
+ return $wpdb->prepare( $sql, $sql_params ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
+ }
+
+ /**
+ * Query for action count or list of action IDs.
+ *
+ * @since 3.3.0 $query['status'] accepts array of statuses instead of a single status.
+ *
+ * @see ActionScheduler_Store::query_actions for $query arg usage.
+ *
+ * @param array $query Query filtering options.
+ * @param string $query_type Whether to select or count the results. Defaults to select.
+ *
+ * @return string|array|null The IDs of actions matching the query. Null on failure.
+ */
+ public function query_actions( $query = array(), $query_type = 'select' ) {
+ /**
+ * Global $wpdb object.
+ *
+ * @var wpdb $wpdb
+ */
+ global $wpdb;
+
+ $sql = $this->get_query_actions_sql( $query, $query_type );
+
+ return ( 'count' === $query_type ) ? $wpdb->get_var( $sql ) : $wpdb->get_col( $sql ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.PreparedSQL.NotPrepared
+ }
+
+ /**
+ * Get a count of all actions in the store, grouped by status
+ *
+ * @return array
+ */
+ public function action_counts() {
+
+ $action_counts_by_status = array();
+ $action_stati_and_labels = $this->get_status_labels();
+ $posts_count_by_status = (array) wp_count_posts( self::POST_TYPE, 'readable' );
+
+ foreach ( $posts_count_by_status as $post_status_name => $count ) {
+
+ try {
+ $action_status_name = $this->get_action_status_by_post_status( $post_status_name );
+ } catch ( Exception $e ) {
+ // Ignore any post statuses that aren't for actions.
+ continue;
+ }
+ if ( array_key_exists( $action_status_name, $action_stati_and_labels ) ) {
+ $action_counts_by_status[ $action_status_name ] = $count;
+ }
+ }
+
+ return $action_counts_by_status;
+ }
+
+ /**
+ * Cancel action.
+ *
+ * @param int $action_id Action ID.
+ *
+ * @throws InvalidArgumentException If $action_id is not identified.
+ */
+ public function cancel_action( $action_id ) {
+ $post = get_post( $action_id );
+ if ( empty( $post ) || ( self::POST_TYPE !== $post->post_type ) ) {
+ /* translators: %s is the action ID */
+ throw new InvalidArgumentException( sprintf( __( 'Unidentified action %s: we were unable to cancel this action. It may may have been deleted by another process.', 'action-scheduler' ), $action_id ) );
+ }
+ do_action( 'action_scheduler_canceled_action', $action_id );
+ add_filter( 'pre_wp_unique_post_slug', array( $this, 'set_unique_post_slug' ), 10, 5 );
+ wp_trash_post( $action_id );
+ remove_filter( 'pre_wp_unique_post_slug', array( $this, 'set_unique_post_slug' ), 10 );
+ }
+
+ /**
+ * Delete action.
+ *
+ * @param int $action_id Action ID.
+ * @return void
+ * @throws InvalidArgumentException If action is not identified.
+ */
+ public function delete_action( $action_id ) {
+ $post = get_post( $action_id );
+ if ( empty( $post ) || ( self::POST_TYPE !== $post->post_type ) ) {
+ /* translators: %s is the action ID */
+ throw new InvalidArgumentException( sprintf( __( 'Unidentified action %s: we were unable to delete this action. It may may have been deleted by another process.', 'action-scheduler' ), $action_id ) );
+ }
+ do_action( 'action_scheduler_deleted_action', $action_id );
+
+ wp_delete_post( $action_id, true );
+ }
+
+ /**
+ * Get date for claim id.
+ *
+ * @param int $action_id Action ID.
+ * @return ActionScheduler_DateTime The date the action is schedule to run, or the date that it ran.
+ */
+ public function get_date( $action_id ) {
+ $next = $this->get_date_gmt( $action_id );
+ return ActionScheduler_TimezoneHelper::set_local_timezone( $next );
+ }
+
+ /**
+ * Get Date GMT.
+ *
+ * @param int $action_id Action ID.
+ *
+ * @throws InvalidArgumentException If $action_id is not identified.
+ * @return ActionScheduler_DateTime The date the action is schedule to run, or the date that it ran.
+ */
+ public function get_date_gmt( $action_id ) {
+ $post = get_post( $action_id );
+ if ( empty( $post ) || ( self::POST_TYPE !== $post->post_type ) ) {
+ /* translators: %s is the action ID */
+ throw new InvalidArgumentException( sprintf( __( 'Unidentified action %s: we were unable to determine the date of this action. It may may have been deleted by another process.', 'action-scheduler' ), $action_id ) );
+ }
+ if ( 'publish' === $post->post_status ) {
+ return as_get_datetime_object( $post->post_modified_gmt );
+ } else {
+ return as_get_datetime_object( $post->post_date_gmt );
+ }
+ }
+
+ /**
+ * Stake claim.
+ *
+ * @param int $max_actions Maximum number of actions.
+ * @param DateTime|null $before_date Jobs must be schedule before this date. Defaults to now.
+ * @param array $hooks Claim only actions with a hook or hooks.
+ * @param string $group Claim only actions in the given group.
+ *
+ * @return ActionScheduler_ActionClaim
+ * @throws RuntimeException When there is an error staking a claim.
+ * @throws InvalidArgumentException When the given group is not valid.
+ */
+ public function stake_claim( $max_actions = 10, ?DateTime $before_date = null, $hooks = array(), $group = '' ) {
+ $this->claim_before_date = $before_date;
+ $claim_id = $this->generate_claim_id();
+ $this->claim_actions( $claim_id, $max_actions, $before_date, $hooks, $group );
+ $action_ids = $this->find_actions_by_claim_id( $claim_id );
+ $this->claim_before_date = null;
+
+ return new ActionScheduler_ActionClaim( $claim_id, $action_ids );
+ }
+
+ /**
+ * Get claim count.
+ *
+ * @return int
+ */
+ public function get_claim_count() {
+ global $wpdb;
+
+ // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
+ return $wpdb->get_var(
+ $wpdb->prepare(
+ "SELECT COUNT(DISTINCT post_password) FROM {$wpdb->posts} WHERE post_password != '' AND post_type = %s AND post_status IN ('in-progress','pending')",
+ array( self::POST_TYPE )
+ )
+ );
+ }
+
+ /**
+ * Generate claim id.
+ *
+ * @return string
+ */
+ protected function generate_claim_id() {
+ $claim_id = md5( microtime( true ) . wp_rand( 0, 1000 ) );
+ return substr( $claim_id, 0, 20 ); // to fit in db field with 20 char limit.
+ }
+
+ /**
+ * Claim actions.
+ *
+ * @param string $claim_id Claim ID.
+ * @param int $limit Limit.
+ * @param DateTime|null $before_date Should use UTC timezone.
+ * @param array $hooks Claim only actions with a hook or hooks.
+ * @param string $group Claim only actions in the given group.
+ *
+ * @return int The number of actions that were claimed.
+ * @throws RuntimeException When there is a database error.
+ */
+ protected function claim_actions( $claim_id, $limit, ?DateTime $before_date = null, $hooks = array(), $group = '' ) {
+ // Set up initial variables.
+ $date = null === $before_date ? as_get_datetime_object() : clone $before_date;
+ $limit_ids = ! empty( $group );
+ $ids = $limit_ids ? $this->get_actions_by_group( $group, $limit, $date ) : array();
+
+ // If limiting by IDs and no posts found, then return early since we have nothing to update.
+ if ( $limit_ids && 0 === count( $ids ) ) {
+ return 0;
+ }
+
+ /**
+ * Global wpdb object.
+ *
+ * @var wpdb $wpdb
+ */
+ global $wpdb;
+
+ /*
+ * Build up custom query to update the affected posts. Parameters are built as a separate array
+ * to make it easier to identify where they are in the query.
+ *
+ * We can't use $wpdb->update() here because of the "ID IN ..." clause.
+ */
+ $update = "UPDATE {$wpdb->posts} SET post_password = %s, post_modified_gmt = %s, post_modified = %s";
+ $params = array(
+ $claim_id,
+ current_time( 'mysql', true ),
+ current_time( 'mysql' ),
+ );
+
+ // Build initial WHERE clause.
+ $where = "WHERE post_type = %s AND post_status = %s AND post_password = ''";
+ $params[] = self::POST_TYPE;
+ $params[] = ActionScheduler_Store::STATUS_PENDING;
+
+ if ( ! empty( $hooks ) ) {
+ $placeholders = array_fill( 0, count( $hooks ), '%s' );
+ $where .= ' AND post_title IN (' . join( ', ', $placeholders ) . ')';
+ $params = array_merge( $params, array_values( $hooks ) );
+ }
+
+ /*
+ * Add the IDs to the WHERE clause. IDs not escaped because they came directly from a prior DB query.
+ *
+ * If we're not limiting by IDs, then include the post_date_gmt clause.
+ */
+ if ( $limit_ids ) {
+ $where .= ' AND ID IN (' . join( ',', $ids ) . ')';
+ } else {
+ $where .= ' AND post_date_gmt <= %s';
+ $params[] = $date->format( 'Y-m-d H:i:s' );
+ }
+
+ // Add the ORDER BY clause and,ms limit.
+ $order = 'ORDER BY menu_order ASC, post_date_gmt ASC, ID ASC LIMIT %d';
+ $params[] = $limit;
+
+ // Run the query and gather results.
+ $rows_affected = $wpdb->query( $wpdb->prepare( "{$update} {$where} {$order}", $params ) ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare
+
+ if ( false === $rows_affected ) {
+ throw new RuntimeException( __( 'Unable to claim actions. Database error.', 'action-scheduler' ) );
+ }
+
+ return (int) $rows_affected;
+ }
+
+ /**
+ * Get IDs of actions within a certain group and up to a certain date/time.
+ *
+ * @param string $group The group to use in finding actions.
+ * @param int $limit The number of actions to retrieve.
+ * @param DateTime $date DateTime object representing cutoff time for actions. Actions retrieved will be
+ * up to and including this DateTime.
+ *
+ * @return array IDs of actions in the appropriate group and before the appropriate time.
+ * @throws InvalidArgumentException When the group does not exist.
+ */
+ protected function get_actions_by_group( $group, $limit, DateTime $date ) {
+ // Ensure the group exists before continuing.
+ if ( ! term_exists( $group, self::GROUP_TAXONOMY ) ) {
+ /* translators: %s is the group name */
+ throw new InvalidArgumentException( sprintf( __( 'The group "%s" does not exist.', 'action-scheduler' ), $group ) );
+ }
+
+ // Set up a query for post IDs to use later.
+ $query = new WP_Query();
+ $query_args = array(
+ 'fields' => 'ids',
+ 'post_type' => self::POST_TYPE,
+ 'post_status' => ActionScheduler_Store::STATUS_PENDING,
+ 'has_password' => false,
+ 'posts_per_page' => $limit * 3,
+ 'suppress_filters' => true, // phpcs:ignore WordPressVIPMinimum.Performance.WPQueryParams.SuppressFilters_suppress_filters
+ 'no_found_rows' => true,
+ 'orderby' => array(
+ 'menu_order' => 'ASC',
+ 'date' => 'ASC',
+ 'ID' => 'ASC',
+ ),
+ 'date_query' => array(
+ 'column' => 'post_date_gmt',
+ 'before' => $date->format( 'Y-m-d H:i' ),
+ 'inclusive' => true,
+ ),
+ 'tax_query' => array( // phpcs:ignore WordPress.DB.SlowDBQuery
+ array(
+ 'taxonomy' => self::GROUP_TAXONOMY,
+ 'field' => 'slug',
+ 'terms' => $group,
+ 'include_children' => false,
+ ),
+ ),
+ );
+
+ return $query->query( $query_args );
+ }
+
+ /**
+ * Find actions by claim ID.
+ *
+ * @param string $claim_id Claim ID.
+ * @return array
+ */
+ public function find_actions_by_claim_id( $claim_id ) {
+ /**
+ * Global wpdb object.
+ *
+ * @var wpdb $wpdb
+ */
+ global $wpdb;
+
+ $action_ids = array();
+ $before_date = isset( $this->claim_before_date ) ? $this->claim_before_date : as_get_datetime_object();
+ $cut_off = $before_date->format( 'Y-m-d H:i:s' );
+
+ // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
+ $results = $wpdb->get_results(
+ $wpdb->prepare(
+ "SELECT ID, post_date_gmt FROM {$wpdb->posts} WHERE post_type = %s AND post_password = %s",
+ array(
+ self::POST_TYPE,
+ $claim_id,
+ )
+ )
+ );
+
+ // Verify that the scheduled date for each action is within the expected bounds (in some unusual
+ // cases, we cannot depend on MySQL to honor all of the WHERE conditions we specify).
+ foreach ( $results as $claimed_action ) {
+ if ( $claimed_action->post_date_gmt <= $cut_off ) {
+ $action_ids[] = absint( $claimed_action->ID );
+ }
+ }
+
+ return $action_ids;
+ }
+
+ /**
+ * Release pending actions from a claim.
+ *
+ * @param ActionScheduler_ActionClaim $claim Claim object to release.
+ * @return void
+ * @throws RuntimeException When the claim is not unlocked.
+ */
+ public function release_claim( ActionScheduler_ActionClaim $claim ) {
+ /**
+ * Global wpdb object.
+ *
+ * @var wpdb $wpdb
+ */
+ global $wpdb;
+
+ $claim_id = $claim->get_id();
+ if ( trim( $claim_id ) === '' ) {
+ // Verify that the claim_id is valid before attempting to release it.
+ return;
+ }
+
+ // Only attempt to release pending actions to be claimed again. Running and complete actions are no longer relevant outside of admin/analytics.
+ // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
+ $action_ids = $wpdb->get_col(
+ $wpdb->prepare(
+ "SELECT ID, post_date_gmt FROM {$wpdb->posts} WHERE post_type = %s AND post_password = %s AND post_status = %s",
+ self::POST_TYPE,
+ $claim_id,
+ self::STATUS_PENDING
+ )
+ );
+
+ if ( empty( $action_ids ) ) {
+ return; // nothing to do.
+ }
+ $action_id_string = implode( ',', array_map( 'intval', $action_ids ) );
+
+ // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
+ $result = $wpdb->query(
+ $wpdb->prepare(
+ "UPDATE {$wpdb->posts} SET post_password = '' WHERE ID IN ($action_id_string) AND post_password = %s", //phpcs:ignore
+ array(
+ $claim->get_id(),
+ )
+ )
+ );
+ if ( false === $result ) {
+ /* translators: %s: claim ID */
+ throw new RuntimeException( sprintf( __( 'Unable to unlock claim %s. Database error.', 'action-scheduler' ), $claim->get_id() ) );
+ }
+ }
+
+ /**
+ * Unclaim action.
+ *
+ * @param string $action_id Action ID.
+ * @throws RuntimeException When unable to unlock claim on action ID.
+ */
+ public function unclaim_action( $action_id ) {
+ /**
+ * Global wpdb object.
+ *
+ * @var wpdb $wpdb
+ */
+ global $wpdb;
+
+ //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
+ $result = $wpdb->query(
+ $wpdb->prepare(
+ "UPDATE {$wpdb->posts} SET post_password = '' WHERE ID = %d AND post_type = %s",
+ $action_id,
+ self::POST_TYPE
+ )
+ );
+ if ( false === $result ) {
+ /* translators: %s: action ID */
+ throw new RuntimeException( sprintf( __( 'Unable to unlock claim on action %s. Database error.', 'action-scheduler' ), $action_id ) );
+ }
+ }
+
+ /**
+ * Mark failure on action.
+ *
+ * @param int $action_id Action ID.
+ *
+ * @return void
+ * @throws RuntimeException When unable to mark failure on action ID.
+ */
+ public function mark_failure( $action_id ) {
+ /**
+ * Global wpdb object.
+ *
+ * @var wpdb $wpdb
+ */
+ global $wpdb;
+
+ // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
+ $result = $wpdb->query(
+ $wpdb->prepare( "UPDATE {$wpdb->posts} SET post_status = %s WHERE ID = %d AND post_type = %s", self::STATUS_FAILED, $action_id, self::POST_TYPE )
+ );
+ if ( false === $result ) {
+ /* translators: %s: action ID */
+ throw new RuntimeException( sprintf( __( 'Unable to mark failure on action %s. Database error.', 'action-scheduler' ), $action_id ) );
+ }
+ }
+
+ /**
+ * Return an action's claim ID, as stored in the post password column
+ *
+ * @param int $action_id Action ID.
+ * @return mixed
+ */
+ public function get_claim_id( $action_id ) {
+ return $this->get_post_column( $action_id, 'post_password' );
+ }
+
+ /**
+ * Return an action's status, as stored in the post status column
+ *
+ * @param int $action_id Action ID.
+ *
+ * @return mixed
+ * @throws InvalidArgumentException When the action ID is invalid.
+ */
+ public function get_status( $action_id ) {
+ $status = $this->get_post_column( $action_id, 'post_status' );
+
+ if ( null === $status ) {
+ throw new InvalidArgumentException( __( 'Invalid action ID. No status found.', 'action-scheduler' ) );
+ }
+
+ return $this->get_action_status_by_post_status( $status );
+ }
+
+ /**
+ * Get post column
+ *
+ * @param string $action_id Action ID.
+ * @param string $column_name Column Name.
+ *
+ * @return string|null
+ */
+ private function get_post_column( $action_id, $column_name ) {
+ /**
+ * Global wpdb object.
+ *
+ * @var wpdb $wpdb
+ */
+ global $wpdb;
+
+ // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
+ return $wpdb->get_var(
+ $wpdb->prepare(
+ "SELECT {$column_name} FROM {$wpdb->posts} WHERE ID=%d AND post_type=%s", // phpcs:ignore
+ $action_id,
+ self::POST_TYPE
+ )
+ );
+ }
+
+ /**
+ * Log Execution.
+ *
+ * @throws Exception If the action status cannot be updated to self::STATUS_RUNNING ('in-progress').
+ *
+ * @param string $action_id Action ID.
+ */
+ public function log_execution( $action_id ) {
+ /**
+ * Global wpdb object.
+ *
+ * @var wpdb $wpdb
+ */
+ global $wpdb;
+
+ // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
+ $status_updated = $wpdb->query(
+ $wpdb->prepare(
+ "UPDATE {$wpdb->posts} SET menu_order = menu_order+1, post_status=%s, post_modified_gmt = %s, post_modified = %s WHERE ID = %d AND post_type = %s",
+ self::STATUS_RUNNING,
+ current_time( 'mysql', true ),
+ current_time( 'mysql' ),
+ $action_id,
+ self::POST_TYPE
+ )
+ );
+
+ if ( ! $status_updated ) {
+ throw new Exception(
+ sprintf(
+ /* translators: 1: action ID. 2: status slug. */
+ __( 'Unable to update the status of action %1$d to %2$s.', 'action-scheduler' ),
+ $action_id,
+ self::STATUS_RUNNING
+ )
+ );
+ }
+ }
+
+ /**
+ * Record that an action was completed.
+ *
+ * @param string $action_id ID of the completed action.
+ *
+ * @throws InvalidArgumentException When the action ID is invalid.
+ * @throws RuntimeException When there was an error executing the action.
+ */
+ public function mark_complete( $action_id ) {
+ $post = get_post( $action_id );
+ if ( empty( $post ) || ( self::POST_TYPE !== $post->post_type ) ) {
+ /* translators: %s is the action ID */
+ throw new InvalidArgumentException( sprintf( __( 'Unidentified action %s: we were unable to mark this action as having completed. It may may have been deleted by another process.', 'action-scheduler' ), $action_id ) );
+ }
+ add_filter( 'wp_insert_post_data', array( $this, 'filter_insert_post_data' ), 10, 1 );
+ add_filter( 'pre_wp_unique_post_slug', array( $this, 'set_unique_post_slug' ), 10, 5 );
+ $result = wp_update_post(
+ array(
+ 'ID' => $action_id,
+ 'post_status' => 'publish',
+ ),
+ true
+ );
+ remove_filter( 'wp_insert_post_data', array( $this, 'filter_insert_post_data' ), 10 );
+ remove_filter( 'pre_wp_unique_post_slug', array( $this, 'set_unique_post_slug' ), 10 );
+ if ( is_wp_error( $result ) ) {
+ throw new RuntimeException( $result->get_error_message() );
+ }
+
+ /**
+ * Fires after a scheduled action has been completed.
+ *
+ * @since 3.4.2
+ *
+ * @param int $action_id Action ID.
+ */
+ do_action( 'action_scheduler_completed_action', $action_id );
+ }
+
+ /**
+ * Mark action as migrated when there is an error deleting the action.
+ *
+ * @param int $action_id Action ID.
+ */
+ public function mark_migrated( $action_id ) {
+ wp_update_post(
+ array(
+ 'ID' => $action_id,
+ 'post_status' => 'migrated',
+ )
+ );
+ }
+
+ /**
+ * Determine whether the post store can be migrated.
+ *
+ * @param [type] $setting - Setting value.
+ * @return bool
+ */
+ public function migration_dependencies_met( $setting ) {
+ global $wpdb;
+
+ $dependencies_met = get_transient( self::DEPENDENCIES_MET );
+ if ( empty( $dependencies_met ) ) {
+ $maximum_args_length = apply_filters( 'action_scheduler_maximum_args_length', 191 );
+ $found_action = $wpdb->get_var( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
+ $wpdb->prepare(
+ "SELECT ID FROM {$wpdb->posts} WHERE post_type = %s AND CHAR_LENGTH(post_content) > %d LIMIT 1",
+ $maximum_args_length,
+ self::POST_TYPE
+ )
+ );
+ $dependencies_met = $found_action ? 'no' : 'yes';
+ set_transient( self::DEPENDENCIES_MET, $dependencies_met, DAY_IN_SECONDS );
+ }
+
+ return 'yes' === $dependencies_met ? $setting : false;
+ }
+
+ /**
+ * InnoDB indexes have a maximum size of 767 bytes by default, which is only 191 characters with utf8mb4.
+ *
+ * Previously, AS wasn't concerned about args length, as we used the (unindex) post_content column. However,
+ * as we prepare to move to custom tables, and can use an indexed VARCHAR column instead, we want to warn
+ * developers of this impending requirement.
+ *
+ * @param ActionScheduler_Action $action Action object.
+ */
+ protected function validate_action( ActionScheduler_Action $action ) {
+ try {
+ parent::validate_action( $action );
+ } catch ( Exception $e ) {
+ /* translators: %s is the error message */
+ $message = sprintf( __( '%s Support for strings longer than this will be removed in a future version.', 'action-scheduler' ), $e->getMessage() );
+ _doing_it_wrong( 'ActionScheduler_Action::$args', esc_html( $message ), '2.1.0' );
+ }
+ }
+
+ /**
+ * (@codeCoverageIgnore)
+ */
+ public function init() {
+ add_filter( 'action_scheduler_migration_dependencies_met', array( $this, 'migration_dependencies_met' ) );
+
+ $post_type_registrar = new ActionScheduler_wpPostStore_PostTypeRegistrar();
+ $post_type_registrar->register();
+
+ $post_status_registrar = new ActionScheduler_wpPostStore_PostStatusRegistrar();
+ $post_status_registrar->register();
+
+ $taxonomy_registrar = new ActionScheduler_wpPostStore_TaxonomyRegistrar();
+ $taxonomy_registrar->register();
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_PostStatusRegistrar.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_PostStatusRegistrar.php
new file mode 100755
index 00000000..5f1f1fc0
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_PostStatusRegistrar.php
@@ -0,0 +1,63 @@
+post_status_args(), $this->post_status_running_labels() ) );
+ register_post_status( ActionScheduler_Store::STATUS_FAILED, array_merge( $this->post_status_args(), $this->post_status_failed_labels() ) );
+ }
+
+ /**
+ * Build the args array for the post type definition
+ *
+ * @return array
+ */
+ protected function post_status_args() {
+ $args = array(
+ 'public' => false,
+ 'exclude_from_search' => false,
+ 'show_in_admin_all_list' => true,
+ 'show_in_admin_status_list' => true,
+ );
+
+ return apply_filters( 'action_scheduler_post_status_args', $args );
+ }
+
+ /**
+ * Build the args array for the post type definition
+ *
+ * @return array
+ */
+ protected function post_status_failed_labels() {
+ $labels = array(
+ 'label' => _x( 'Failed', 'post', 'action-scheduler' ),
+ /* translators: %s: count */
+ 'label_count' => _n_noop( 'Failed (%s)', 'Failed (%s)', 'action-scheduler' ),
+ );
+
+ return apply_filters( 'action_scheduler_post_status_failed_labels', $labels );
+ }
+
+ /**
+ * Build the args array for the post type definition
+ *
+ * @return array
+ */
+ protected function post_status_running_labels() {
+ $labels = array(
+ 'label' => _x( 'In-Progress', 'post', 'action-scheduler' ),
+ /* translators: %s: count */
+ 'label_count' => _n_noop( 'In-Progress (%s)', 'In-Progress (%s)', 'action-scheduler' ),
+ );
+
+ return apply_filters( 'action_scheduler_post_status_running_labels', $labels );
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_PostTypeRegistrar.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_PostTypeRegistrar.php
new file mode 100755
index 00000000..52522945
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_PostTypeRegistrar.php
@@ -0,0 +1,53 @@
+post_type_args() );
+ }
+
+ /**
+ * Build the args array for the post type definition
+ *
+ * @return array
+ */
+ protected function post_type_args() {
+ $args = array(
+ 'label' => __( 'Scheduled Actions', 'action-scheduler' ),
+ 'description' => __( 'Scheduled actions are hooks triggered on a certain date and time.', 'action-scheduler' ),
+ 'public' => false,
+ 'map_meta_cap' => true,
+ 'hierarchical' => false,
+ 'supports' => array( 'title', 'editor', 'comments' ),
+ 'rewrite' => false,
+ 'query_var' => false,
+ 'can_export' => true,
+ 'ep_mask' => EP_NONE,
+ 'labels' => array(
+ 'name' => __( 'Scheduled Actions', 'action-scheduler' ),
+ 'singular_name' => __( 'Scheduled Action', 'action-scheduler' ),
+ 'menu_name' => _x( 'Scheduled Actions', 'Admin menu name', 'action-scheduler' ),
+ 'add_new' => __( 'Add', 'action-scheduler' ),
+ 'add_new_item' => __( 'Add New Scheduled Action', 'action-scheduler' ),
+ 'edit' => __( 'Edit', 'action-scheduler' ),
+ 'edit_item' => __( 'Edit Scheduled Action', 'action-scheduler' ),
+ 'new_item' => __( 'New Scheduled Action', 'action-scheduler' ),
+ 'view' => __( 'View Action', 'action-scheduler' ),
+ 'view_item' => __( 'View Action', 'action-scheduler' ),
+ 'search_items' => __( 'Search Scheduled Actions', 'action-scheduler' ),
+ 'not_found' => __( 'No actions found', 'action-scheduler' ),
+ 'not_found_in_trash' => __( 'No actions found in trash', 'action-scheduler' ),
+ ),
+ );
+
+ $args = apply_filters( 'action_scheduler_post_type_args', $args );
+ return $args;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_TaxonomyRegistrar.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_TaxonomyRegistrar.php
new file mode 100755
index 00000000..e100fc9b
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_TaxonomyRegistrar.php
@@ -0,0 +1,33 @@
+taxonomy_args() );
+ }
+
+ /**
+ * Get taxonomy arguments.
+ */
+ protected function taxonomy_args() {
+ $args = array(
+ 'label' => __( 'Action Group', 'action-scheduler' ),
+ 'public' => false,
+ 'hierarchical' => false,
+ 'show_admin_column' => true,
+ 'query_var' => false,
+ 'rewrite' => false,
+ );
+
+ $args = apply_filters( 'action_scheduler_taxonomy_args', $args );
+ return $args;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/migration/ActionMigrator.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/migration/ActionMigrator.php
new file mode 100755
index 00000000..f0e04fe9
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/migration/ActionMigrator.php
@@ -0,0 +1,126 @@
+source = $source_store;
+ $this->destination = $destination_store;
+ $this->log_migrator = $log_migrator;
+ }
+
+ /**
+ * Migrate an action.
+ *
+ * @param int $source_action_id Action ID.
+ *
+ * @return int 0|new action ID
+ * @throws \RuntimeException When unable to delete action from the source store.
+ */
+ public function migrate( $source_action_id ) {
+ try {
+ $action = $this->source->fetch_action( $source_action_id );
+ $status = $this->source->get_status( $source_action_id );
+ } catch ( \Exception $e ) {
+ $action = null;
+ $status = '';
+ }
+
+ if ( is_null( $action ) || empty( $status ) || ! $action->get_schedule()->get_date() ) {
+ // null action or empty status means the fetch operation failed or the action didn't exist.
+ // null schedule means it's missing vital data.
+ // delete it and move on.
+ try {
+ $this->source->delete_action( $source_action_id );
+ } catch ( \Exception $e ) { // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedCatch
+ // nothing to do, it didn't exist in the first place.
+ }
+ do_action( 'action_scheduler/no_action_to_migrate', $source_action_id, $this->source, $this->destination ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
+
+ return 0;
+ }
+
+ try {
+
+ // Make sure the last attempt date is set correctly for completed and failed actions.
+ $last_attempt_date = ( \ActionScheduler_Store::STATUS_PENDING !== $status ) ? $this->source->get_date( $source_action_id ) : null;
+
+ $destination_action_id = $this->destination->save_action( $action, null, $last_attempt_date );
+ } catch ( \Exception $e ) {
+ do_action( 'action_scheduler/migrate_action_failed', $source_action_id, $this->source, $this->destination ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
+
+ return 0; // could not save the action in the new store.
+ }
+
+ try {
+ switch ( $status ) {
+ case \ActionScheduler_Store::STATUS_FAILED:
+ $this->destination->mark_failure( $destination_action_id );
+ break;
+ case \ActionScheduler_Store::STATUS_CANCELED:
+ $this->destination->cancel_action( $destination_action_id );
+ break;
+ }
+
+ $this->log_migrator->migrate( $source_action_id, $destination_action_id );
+ $this->source->delete_action( $source_action_id );
+
+ $test_action = $this->source->fetch_action( $source_action_id );
+ if ( ! is_a( $test_action, 'ActionScheduler_NullAction' ) ) {
+ // translators: %s is an action ID.
+ throw new \RuntimeException( sprintf( __( 'Unable to remove source migrated action %s', 'action-scheduler' ), $source_action_id ) );
+ }
+ do_action( 'action_scheduler/migrated_action', $source_action_id, $destination_action_id, $this->source, $this->destination ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
+
+ return $destination_action_id;
+ } catch ( \Exception $e ) {
+ // could not delete from the old store.
+ $this->source->mark_migrated( $source_action_id );
+
+ // phpcs:disable WordPress.NamingConventions.ValidHookName.UseUnderscores
+ do_action( 'action_scheduler/migrate_action_incomplete', $source_action_id, $destination_action_id, $this->source, $this->destination );
+ do_action( 'action_scheduler/migrated_action', $source_action_id, $destination_action_id, $this->source, $this->destination );
+ // phpcs:enable
+
+ return $destination_action_id;
+ }
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/migration/ActionScheduler_DBStoreMigrator.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/migration/ActionScheduler_DBStoreMigrator.php
new file mode 100755
index 00000000..66ab9970
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/migration/ActionScheduler_DBStoreMigrator.php
@@ -0,0 +1,52 @@
+ $this->get_scheduled_date_string( $action, $last_attempt_date ),
+ 'last_attempt_local' => $this->get_scheduled_date_string_local( $action, $last_attempt_date ),
+ );
+
+ $wpdb->update( $wpdb->actionscheduler_actions, $data, array( 'action_id' => $action_id ), array( '%s', '%s' ), array( '%d' ) );
+ }
+
+ return $action_id;
+ } catch ( \Exception $e ) {
+ // translators: %s is an error message.
+ throw new \RuntimeException( sprintf( __( 'Error saving action: %s', 'action-scheduler' ), $e->getMessage() ), 0 );
+ }
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/migration/BatchFetcher.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/migration/BatchFetcher.php
new file mode 100755
index 00000000..20aa3d03
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/migration/BatchFetcher.php
@@ -0,0 +1,95 @@
+store = $source_store;
+ }
+
+ /**
+ * Retrieve a list of actions.
+ *
+ * @param int $count The number of actions to retrieve.
+ *
+ * @return int[] A list of action IDs
+ */
+ public function fetch( $count = 10 ) {
+ foreach ( $this->get_query_strategies( $count ) as $query ) {
+ $action_ids = $this->store->query_actions( $query );
+ if ( ! empty( $action_ids ) ) {
+ return $action_ids;
+ }
+ }
+
+ return array();
+ }
+
+ /**
+ * Generate a list of prioritized of action search parameters.
+ *
+ * @param int $count Number of actions to find.
+ *
+ * @return array
+ */
+ private function get_query_strategies( $count ) {
+ $now = as_get_datetime_object();
+ $args = array(
+ 'date' => $now,
+ 'per_page' => $count,
+ 'offset' => 0,
+ 'orderby' => 'date',
+ 'order' => 'ASC',
+ );
+
+ $priorities = array(
+ Store::STATUS_PENDING,
+ Store::STATUS_FAILED,
+ Store::STATUS_CANCELED,
+ Store::STATUS_COMPLETE,
+ Store::STATUS_RUNNING,
+ '', // any other unanticipated status.
+ );
+
+ foreach ( $priorities as $status ) {
+ yield wp_parse_args(
+ array(
+ 'status' => $status,
+ 'date_compare' => '<=',
+ ),
+ $args
+ );
+
+ yield wp_parse_args(
+ array(
+ 'status' => $status,
+ 'date_compare' => '>=',
+ ),
+ $args
+ );
+ }
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/migration/Config.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/migration/Config.php
new file mode 100755
index 00000000..f16b4c19
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/migration/Config.php
@@ -0,0 +1,196 @@
+source_store ) ) {
+ throw new \RuntimeException( __( 'Source store must be configured before running a migration', 'action-scheduler' ) );
+ }
+
+ return $this->source_store;
+ }
+
+ /**
+ * Set the configured source store.
+ *
+ * @param ActionScheduler_Store $store Source store object.
+ */
+ public function set_source_store( Store $store ) {
+ $this->source_store = $store;
+ }
+
+ /**
+ * Get the configured source logger.
+ *
+ * @return ActionScheduler_Logger
+ * @throws \RuntimeException When source logger is not configured.
+ */
+ public function get_source_logger() {
+ if ( empty( $this->source_logger ) ) {
+ throw new \RuntimeException( __( 'Source logger must be configured before running a migration', 'action-scheduler' ) );
+ }
+
+ return $this->source_logger;
+ }
+
+ /**
+ * Set the configured source logger.
+ *
+ * @param ActionScheduler_Logger $logger Logger object.
+ */
+ public function set_source_logger( Logger $logger ) {
+ $this->source_logger = $logger;
+ }
+
+ /**
+ * Get the configured destination store.
+ *
+ * @return ActionScheduler_Store
+ * @throws \RuntimeException When destination store is not configured.
+ */
+ public function get_destination_store() {
+ if ( empty( $this->destination_store ) ) {
+ throw new \RuntimeException( __( 'Destination store must be configured before running a migration', 'action-scheduler' ) );
+ }
+
+ return $this->destination_store;
+ }
+
+ /**
+ * Set the configured destination store.
+ *
+ * @param ActionScheduler_Store $store Action store object.
+ */
+ public function set_destination_store( Store $store ) {
+ $this->destination_store = $store;
+ }
+
+ /**
+ * Get the configured destination logger.
+ *
+ * @return ActionScheduler_Logger
+ * @throws \RuntimeException When destination logger is not configured.
+ */
+ public function get_destination_logger() {
+ if ( empty( $this->destination_logger ) ) {
+ throw new \RuntimeException( __( 'Destination logger must be configured before running a migration', 'action-scheduler' ) );
+ }
+
+ return $this->destination_logger;
+ }
+
+ /**
+ * Set the configured destination logger.
+ *
+ * @param ActionScheduler_Logger $logger Logger object.
+ */
+ public function set_destination_logger( Logger $logger ) {
+ $this->destination_logger = $logger;
+ }
+
+ /**
+ * Get flag indicating whether it's a dry run.
+ *
+ * @return bool
+ */
+ public function get_dry_run() {
+ return $this->dry_run;
+ }
+
+ /**
+ * Set flag indicating whether it's a dry run.
+ *
+ * @param bool $dry_run Dry run toggle.
+ */
+ public function set_dry_run( $dry_run ) {
+ $this->dry_run = (bool) $dry_run;
+ }
+
+ /**
+ * Get progress bar object.
+ *
+ * @return ActionScheduler\WPCLI\ProgressBar
+ */
+ public function get_progress_bar() {
+ return $this->progress_bar;
+ }
+
+ /**
+ * Set progress bar object.
+ *
+ * @param ActionScheduler\WPCLI\ProgressBar $progress_bar Progress bar object.
+ */
+ public function set_progress_bar( ProgressBar $progress_bar ) {
+ $this->progress_bar = $progress_bar;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/migration/Controller.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/migration/Controller.php
new file mode 100755
index 00000000..7c3df607
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/migration/Controller.php
@@ -0,0 +1,245 @@
+migration_scheduler = $migration_scheduler;
+ $this->store_classname = '';
+ }
+
+ /**
+ * Set the action store class name.
+ *
+ * @param string $class Classname of the store class.
+ *
+ * @return string
+ */
+ public function get_store_class( $class ) {
+ if ( \ActionScheduler_DataController::is_migration_complete() ) {
+ return \ActionScheduler_DataController::DATASTORE_CLASS;
+ } elseif ( \ActionScheduler_Store::DEFAULT_CLASS !== $class ) {
+ $this->store_classname = $class;
+ return $class;
+ } else {
+ return 'ActionScheduler_HybridStore';
+ }
+ }
+
+ /**
+ * Set the action logger class name.
+ *
+ * @param string $class Classname of the logger class.
+ *
+ * @return string
+ */
+ public function get_logger_class( $class ) {
+ \ActionScheduler_Store::instance();
+
+ if ( $this->has_custom_datastore() ) {
+ $this->logger_classname = $class;
+ return $class;
+ } else {
+ return \ActionScheduler_DataController::LOGGER_CLASS;
+ }
+ }
+
+ /**
+ * Get flag indicating whether a custom datastore is in use.
+ *
+ * @return bool
+ */
+ public function has_custom_datastore() {
+ return (bool) $this->store_classname;
+ }
+
+ /**
+ * Set up the background migration process.
+ *
+ * @return void
+ */
+ public function schedule_migration() {
+ $logging_tables = new ActionScheduler_LoggerSchema();
+ $store_tables = new ActionScheduler_StoreSchema();
+
+ /*
+ * In some unusual cases, the expected tables may not have been created. In such cases
+ * we do not schedule a migration as doing so will lead to fatal error conditions.
+ *
+ * In such cases the user will likely visit the Tools > Scheduled Actions screen to
+ * investigate, and will see appropriate messaging (this step also triggers an attempt
+ * to rebuild any missing tables).
+ *
+ * @see https://github.com/woocommerce/action-scheduler/issues/653
+ */
+ if (
+ ActionScheduler_DataController::is_migration_complete()
+ || $this->migration_scheduler->is_migration_scheduled()
+ || ! $store_tables->tables_exist()
+ || ! $logging_tables->tables_exist()
+ ) {
+ return;
+ }
+
+ $this->migration_scheduler->schedule_migration();
+ }
+
+ /**
+ * Get the default migration config object
+ *
+ * @return ActionScheduler\Migration\Config
+ */
+ public function get_migration_config_object() {
+ static $config = null;
+
+ if ( ! $config ) {
+ $source_store = $this->store_classname ? new $this->store_classname() : new \ActionScheduler_wpPostStore();
+ $source_logger = $this->logger_classname ? new $this->logger_classname() : new \ActionScheduler_wpCommentLogger();
+
+ $config = new Config();
+ $config->set_source_store( $source_store );
+ $config->set_source_logger( $source_logger );
+ $config->set_destination_store( new \ActionScheduler_DBStoreMigrator() );
+ $config->set_destination_logger( new \ActionScheduler_DBLogger() );
+
+ if ( defined( 'WP_CLI' ) && WP_CLI ) {
+ $config->set_progress_bar( new ProgressBar( '', 0 ) );
+ }
+ }
+
+ return apply_filters( 'action_scheduler/migration_config', $config ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
+ }
+
+ /**
+ * Hook dashboard migration notice.
+ */
+ public function hook_admin_notices() {
+ if ( ! $this->allow_migration() || \ActionScheduler_DataController::is_migration_complete() ) {
+ return;
+ }
+ add_action( 'admin_notices', array( $this, 'display_migration_notice' ), 10, 0 );
+ }
+
+ /**
+ * Show a dashboard notice that migration is in progress.
+ */
+ public function display_migration_notice() {
+ printf( '
%s
', esc_html__( 'Action Scheduler migration in progress. The list of scheduled actions may be incomplete.', 'action-scheduler' ) );
+ }
+
+ /**
+ * Add store classes. Hook migration.
+ */
+ private function hook() {
+ add_filter( 'action_scheduler_store_class', array( $this, 'get_store_class' ), 100, 1 );
+ add_filter( 'action_scheduler_logger_class', array( $this, 'get_logger_class' ), 100, 1 );
+ add_action( 'init', array( $this, 'maybe_hook_migration' ) );
+ add_action( 'wp_loaded', array( $this, 'schedule_migration' ) );
+
+ // Action Scheduler may be displayed as a Tools screen or WooCommerce > Status administration screen.
+ add_action( 'load-tools_page_action-scheduler', array( $this, 'hook_admin_notices' ), 10, 0 );
+ add_action( 'load-woocommerce_page_wc-status', array( $this, 'hook_admin_notices' ), 10, 0 );
+ }
+
+ /**
+ * Possibly hook the migration scheduler action.
+ */
+ public function maybe_hook_migration() {
+ if ( ! $this->allow_migration() || \ActionScheduler_DataController::is_migration_complete() ) {
+ return;
+ }
+
+ $this->migration_scheduler->hook();
+ }
+
+ /**
+ * Allow datastores to enable migration to AS tables.
+ */
+ public function allow_migration() {
+ if ( ! \ActionScheduler_DataController::dependencies_met() ) {
+ return false;
+ }
+
+ if ( null === $this->migrate_custom_store ) {
+ $this->migrate_custom_store = apply_filters( 'action_scheduler_migrate_data_store', false );
+ }
+
+ return ( ! $this->has_custom_datastore() ) || $this->migrate_custom_store;
+ }
+
+ /**
+ * Proceed with the migration if the dependencies have been met.
+ */
+ public static function init() {
+ if ( \ActionScheduler_DataController::dependencies_met() ) {
+ self::instance()->hook();
+ }
+ }
+
+ /**
+ * Singleton factory.
+ */
+ public static function instance() {
+ if ( ! isset( self::$instance ) ) {
+ self::$instance = new static( new Scheduler() );
+ }
+
+ return self::$instance;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/migration/DryRun_ActionMigrator.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/migration/DryRun_ActionMigrator.php
new file mode 100755
index 00000000..ab7d670e
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/migration/DryRun_ActionMigrator.php
@@ -0,0 +1,28 @@
+source = $source_logger;
+ $this->destination = $destination_logger;
+ }
+
+ /**
+ * Migrate an action log.
+ *
+ * @param int $source_action_id Source logger object.
+ * @param int $destination_action_id Destination logger object.
+ */
+ public function migrate( $source_action_id, $destination_action_id ) {
+ $logs = $this->source->get_logs( $source_action_id );
+
+ foreach ( $logs as $log ) {
+ if ( absint( $log->get_action_id() ) === absint( $source_action_id ) ) {
+ $this->destination->log( $destination_action_id, $log->get_message(), $log->get_date() );
+ }
+ }
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/migration/Runner.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/migration/Runner.php
new file mode 100755
index 00000000..85c7e044
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/migration/Runner.php
@@ -0,0 +1,171 @@
+source_store = $config->get_source_store();
+ $this->destination_store = $config->get_destination_store();
+ $this->source_logger = $config->get_source_logger();
+ $this->destination_logger = $config->get_destination_logger();
+
+ $this->batch_fetcher = new BatchFetcher( $this->source_store );
+ if ( $config->get_dry_run() ) {
+ $this->log_migrator = new DryRun_LogMigrator( $this->source_logger, $this->destination_logger );
+ $this->action_migrator = new DryRun_ActionMigrator( $this->source_store, $this->destination_store, $this->log_migrator );
+ } else {
+ $this->log_migrator = new LogMigrator( $this->source_logger, $this->destination_logger );
+ $this->action_migrator = new ActionMigrator( $this->source_store, $this->destination_store, $this->log_migrator );
+ }
+
+ if ( defined( 'WP_CLI' ) && WP_CLI ) {
+ $this->progress_bar = $config->get_progress_bar();
+ }
+ }
+
+ /**
+ * Run migration batch.
+ *
+ * @param int $batch_size Optional batch size. Default 10.
+ *
+ * @return int Size of batch processed.
+ */
+ public function run( $batch_size = 10 ) {
+ $batch = $this->batch_fetcher->fetch( $batch_size );
+ $batch_size = count( $batch );
+
+ if ( ! $batch_size ) {
+ return 0;
+ }
+
+ if ( $this->progress_bar ) {
+ /* translators: %d: amount of actions */
+ $this->progress_bar->set_message( sprintf( _n( 'Migrating %d action', 'Migrating %d actions', $batch_size, 'action-scheduler' ), $batch_size ) );
+ $this->progress_bar->set_count( $batch_size );
+ }
+
+ $this->migrate_actions( $batch );
+
+ return $batch_size;
+ }
+
+ /**
+ * Migration a batch of actions.
+ *
+ * @param array $action_ids List of action IDs to migrate.
+ */
+ public function migrate_actions( array $action_ids ) {
+ do_action( 'action_scheduler/migration_batch_starting', $action_ids ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
+
+ \ActionScheduler::logger()->unhook_stored_action();
+ $this->destination_logger->unhook_stored_action();
+
+ foreach ( $action_ids as $source_action_id ) {
+ $destination_action_id = $this->action_migrator->migrate( $source_action_id );
+ if ( $destination_action_id ) {
+ $this->destination_logger->log(
+ $destination_action_id,
+ sprintf(
+ /* translators: 1: source action ID 2: source store class 3: destination action ID 4: destination store class */
+ __( 'Migrated action with ID %1$d in %2$s to ID %3$d in %4$s', 'action-scheduler' ),
+ $source_action_id,
+ get_class( $this->source_store ),
+ $destination_action_id,
+ get_class( $this->destination_store )
+ )
+ );
+ }
+
+ if ( $this->progress_bar ) {
+ $this->progress_bar->tick();
+ }
+ }
+
+ if ( $this->progress_bar ) {
+ $this->progress_bar->finish();
+ }
+
+ \ActionScheduler::logger()->hook_stored_action();
+
+ do_action( 'action_scheduler/migration_batch_complete', $action_ids ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
+ }
+
+ /**
+ * Initialize destination store and logger.
+ */
+ public function init_destination() {
+ $this->destination_store->init();
+ $this->destination_logger->init();
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/migration/Scheduler.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/migration/Scheduler.php
new file mode 100755
index 00000000..d6c320d9
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/migration/Scheduler.php
@@ -0,0 +1,128 @@
+get_migration_runner();
+ $count = $migration_runner->run( $this->get_batch_size() );
+
+ if ( 0 === $count ) {
+ $this->mark_complete();
+ } else {
+ $this->schedule_migration( time() + $this->get_schedule_interval() );
+ }
+ }
+
+ /**
+ * Mark the migration complete.
+ */
+ public function mark_complete() {
+ $this->unschedule_migration();
+
+ \ActionScheduler_DataController::mark_migration_complete();
+ do_action( 'action_scheduler/migration_complete' ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
+ }
+
+ /**
+ * Get a flag indicating whether the migration is scheduled.
+ *
+ * @return bool Whether there is a pending action in the store to handle the migration
+ */
+ public function is_migration_scheduled() {
+ $next = as_next_scheduled_action( self::HOOK );
+
+ return ! empty( $next );
+ }
+
+ /**
+ * Schedule the migration.
+ *
+ * @param int $when Optional timestamp to run the next migration batch. Defaults to now.
+ *
+ * @return string The action ID
+ */
+ public function schedule_migration( $when = 0 ) {
+ $next = as_next_scheduled_action( self::HOOK );
+
+ if ( ! empty( $next ) ) {
+ return $next;
+ }
+
+ if ( empty( $when ) ) {
+ $when = time() + MINUTE_IN_SECONDS;
+ }
+
+ return as_schedule_single_action( $when, self::HOOK, array(), self::GROUP );
+ }
+
+ /**
+ * Remove the scheduled migration action.
+ */
+ public function unschedule_migration() {
+ as_unschedule_action( self::HOOK, null, self::GROUP );
+ }
+
+ /**
+ * Get migration batch schedule interval.
+ *
+ * @return int Seconds between migration runs. Defaults to 0 seconds to allow chaining migration via Async Runners.
+ */
+ private function get_schedule_interval() {
+ return (int) apply_filters( 'action_scheduler/migration_interval', 0 ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
+ }
+
+ /**
+ * Get migration batch size.
+ *
+ * @return int Number of actions to migrate in each batch. Defaults to 250.
+ */
+ private function get_batch_size() {
+ return (int) apply_filters( 'action_scheduler/migration_batch_size', 250 ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
+ }
+
+ /**
+ * Get migration runner object.
+ *
+ * @return Runner
+ */
+ private function get_migration_runner() {
+ $config = Controller::instance()->get_migration_config_object();
+
+ return new Runner( $config );
+ }
+
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/schedules/ActionScheduler_CanceledSchedule.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/schedules/ActionScheduler_CanceledSchedule.php
new file mode 100755
index 00000000..4f90c833
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/schedules/ActionScheduler_CanceledSchedule.php
@@ -0,0 +1,63 @@
+__wakeup() for details.
+ *
+ * @var null
+ */
+ private $timestamp = null;
+
+ /**
+ * Calculate when the next instance of this schedule would run based on a given date & time.
+ *
+ * @param DateTime $after Timestamp.
+ *
+ * @return DateTime|null
+ */
+ public function calculate_next( DateTime $after ) {
+ return null;
+ }
+
+ /**
+ * Cancelled actions should never have a next schedule, even if get_next()
+ * is called with $after < $this->scheduled_date.
+ *
+ * @param DateTime $after Timestamp.
+ * @return DateTime|null
+ */
+ public function get_next( DateTime $after ) {
+ return null;
+ }
+
+ /**
+ * Action is not recurring.
+ *
+ * @return bool
+ */
+ public function is_recurring() {
+ return false;
+ }
+
+ /**
+ * Unserialize recurring schedules serialized/stored prior to AS 3.0.0
+ *
+ * Prior to Action Scheduler 3.0.0, schedules used different property names to refer
+ * to equivalent data. For example, ActionScheduler_IntervalSchedule::start_timestamp
+ * was the same as ActionScheduler_SimpleSchedule::timestamp. Action Scheduler 3.0.0
+ * aligned properties and property names for better inheritance. To maintain backward
+ * compatibility with schedules serialized and stored prior to 3.0, we need to correctly
+ * map the old property names with matching visibility.
+ */
+ public function __wakeup() {
+ if ( ! is_null( $this->timestamp ) ) {
+ $this->scheduled_timestamp = $this->timestamp;
+ unset( $this->timestamp );
+ }
+ parent::__wakeup();
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/schedules/ActionScheduler_CronSchedule.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/schedules/ActionScheduler_CronSchedule.php
new file mode 100755
index 00000000..6ac43c94
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/schedules/ActionScheduler_CronSchedule.php
@@ -0,0 +1,111 @@
+__wakeup() for details.
+ *
+ * @var null
+ */
+ private $start_timestamp = null;
+
+ /**
+ * Deprecated property @see $this->__wakeup() for details.
+ *
+ * @var null
+ */
+ private $cron = null;
+
+ /**
+ * Wrapper for parent constructor to accept a cron expression string and map it to a CronExpression for this
+ * objects $recurrence property.
+ *
+ * @param DateTime $start The date & time to run the action at or after. If $start aligns with the CronSchedule passed via $recurrence, it will be used. If it does not align, the first matching date after it will be used.
+ * @param CronExpression|string $recurrence The CronExpression used to calculate the schedule's next instance.
+ * @param DateTime|null $first (Optional) The date & time the first instance of this interval schedule ran. Default null, meaning this is the first instance.
+ */
+ public function __construct( DateTime $start, $recurrence, ?DateTime $first = null ) {
+ if ( ! is_a( $recurrence, 'CronExpression' ) ) {
+ $recurrence = CronExpression::factory( $recurrence );
+ }
+
+ // For backward compatibility, we need to make sure the date is set to the first matching cron date, not whatever date is passed in. Importantly, by passing true as the 3rd param, if $start matches the cron expression, then it will be used. This was previously handled in the now deprecated next() method.
+ $date = $recurrence->getNextRunDate( $start, 0, true );
+
+ // parent::__construct() will set this to $date by default, but that may be different to $start now.
+ $first = empty( $first ) ? $start : $first;
+
+ parent::__construct( $date, $recurrence, $first );
+ }
+
+ /**
+ * Calculate when an instance of this schedule would start based on a given
+ * date & time using its the CronExpression.
+ *
+ * @param DateTime $after Timestamp.
+ * @return DateTime
+ */
+ protected function calculate_next( DateTime $after ) {
+ return $this->recurrence->getNextRunDate( $after, 0, false );
+ }
+
+ /**
+ * Get the schedule's recurrence.
+ *
+ * @return string
+ */
+ public function get_recurrence() {
+ return strval( $this->recurrence );
+ }
+
+ /**
+ * Serialize cron schedules with data required prior to AS 3.0.0
+ *
+ * Prior to Action Scheduler 3.0.0, recurring schedules used different property names to
+ * refer to equivalent data. For example, ActionScheduler_IntervalSchedule::start_timestamp
+ * was the same as ActionScheduler_SimpleSchedule::timestamp. Action Scheduler 3.0.0
+ * aligned properties and property names for better inheritance. To guard against the
+ * possibility of infinite loops if downgrading to Action Scheduler < 3.0.0, we need to
+ * also store the data with the old property names so if it's unserialized in AS < 3.0,
+ * the schedule doesn't end up with a null recurrence.
+ *
+ * @return array
+ */
+ public function __sleep() {
+
+ $sleep_params = parent::__sleep();
+
+ $this->start_timestamp = $this->scheduled_timestamp;
+ $this->cron = $this->recurrence;
+
+ return array_merge(
+ $sleep_params,
+ array(
+ 'start_timestamp',
+ 'cron',
+ )
+ );
+ }
+
+ /**
+ * Unserialize cron schedules serialized/stored prior to AS 3.0.0
+ *
+ * For more background, @see ActionScheduler_Abstract_RecurringSchedule::__wakeup().
+ */
+ public function __wakeup() {
+ if ( is_null( $this->scheduled_timestamp ) && ! is_null( $this->start_timestamp ) ) {
+ $this->scheduled_timestamp = $this->start_timestamp;
+ unset( $this->start_timestamp );
+ }
+
+ if ( is_null( $this->recurrence ) && ! is_null( $this->cron ) ) {
+ $this->recurrence = $this->cron;
+ unset( $this->cron );
+ }
+ parent::__wakeup();
+ }
+}
+
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/schedules/ActionScheduler_IntervalSchedule.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/schedules/ActionScheduler_IntervalSchedule.php
new file mode 100755
index 00000000..228ef4c2
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/schedules/ActionScheduler_IntervalSchedule.php
@@ -0,0 +1,90 @@
+__wakeup() for details.
+ *
+ * @var null
+ */
+ private $start_timestamp = null;
+
+ /**
+ * Deprecated property @see $this->__wakeup() for details.
+ *
+ * @var null
+ */
+ private $interval_in_seconds = null;
+
+ /**
+ * Calculate when this schedule should start after a given date & time using
+ * the number of seconds between recurrences.
+ *
+ * @param DateTime $after Timestamp.
+ * @return DateTime
+ */
+ protected function calculate_next( DateTime $after ) {
+ $after->modify( '+' . (int) $this->get_recurrence() . ' seconds' );
+ return $after;
+ }
+
+ /**
+ * Schedule interval in seconds.
+ *
+ * @return int
+ */
+ public function interval_in_seconds() {
+ _deprecated_function( __METHOD__, '3.0.0', '(int)ActionScheduler_Abstract_RecurringSchedule::get_recurrence()' );
+ return (int) $this->get_recurrence();
+ }
+
+ /**
+ * Serialize interval schedules with data required prior to AS 3.0.0
+ *
+ * Prior to Action Scheduler 3.0.0, recurring schedules used different property names to
+ * refer to equivalent data. For example, ActionScheduler_IntervalSchedule::start_timestamp
+ * was the same as ActionScheduler_SimpleSchedule::timestamp. Action Scheduler 3.0.0
+ * aligned properties and property names for better inheritance. To guard against the
+ * possibility of infinite loops if downgrading to Action Scheduler < 3.0.0, we need to
+ * also store the data with the old property names so if it's unserialized in AS < 3.0,
+ * the schedule doesn't end up with a null/false/0 recurrence.
+ *
+ * @return array
+ */
+ public function __sleep() {
+
+ $sleep_params = parent::__sleep();
+
+ $this->start_timestamp = $this->scheduled_timestamp;
+ $this->interval_in_seconds = $this->recurrence;
+
+ return array_merge(
+ $sleep_params,
+ array(
+ 'start_timestamp',
+ 'interval_in_seconds',
+ )
+ );
+ }
+
+ /**
+ * Unserialize interval schedules serialized/stored prior to AS 3.0.0
+ *
+ * For more background, @see ActionScheduler_Abstract_RecurringSchedule::__wakeup().
+ */
+ public function __wakeup() {
+ if ( is_null( $this->scheduled_timestamp ) && ! is_null( $this->start_timestamp ) ) {
+ $this->scheduled_timestamp = $this->start_timestamp;
+ unset( $this->start_timestamp );
+ }
+
+ if ( is_null( $this->recurrence ) && ! is_null( $this->interval_in_seconds ) ) {
+ $this->recurrence = $this->interval_in_seconds;
+ unset( $this->interval_in_seconds );
+ }
+ parent::__wakeup();
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/schedules/ActionScheduler_NullSchedule.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/schedules/ActionScheduler_NullSchedule.php
new file mode 100755
index 00000000..77c7c4ed
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/schedules/ActionScheduler_NullSchedule.php
@@ -0,0 +1,39 @@
+scheduled_date = null;
+ }
+
+ /**
+ * This schedule has no scheduled DateTime, so we need to override the parent __sleep().
+ *
+ * @return array
+ */
+ public function __sleep() {
+ return array();
+ }
+
+ /**
+ * Wakeup.
+ */
+ public function __wakeup() {
+ $this->scheduled_date = null;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/schedules/ActionScheduler_Schedule.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/schedules/ActionScheduler_Schedule.php
new file mode 100755
index 00000000..e3803e18
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/schedules/ActionScheduler_Schedule.php
@@ -0,0 +1,22 @@
+__wakeup() for details.
+ *
+ * @var null|DateTime
+ */
+ private $timestamp = null;
+
+ /**
+ * Calculate when this schedule should start after a given date & time using
+ * the number of seconds between recurrences.
+ *
+ * @param DateTime $after Timestamp.
+ *
+ * @return DateTime|null
+ */
+ public function calculate_next( DateTime $after ) {
+ return null;
+ }
+
+ /**
+ * Schedule is not recurring.
+ *
+ * @return bool
+ */
+ public function is_recurring() {
+ return false;
+ }
+
+ /**
+ * Serialize schedule with data required prior to AS 3.0.0
+ *
+ * Prior to Action Scheduler 3.0.0, schedules used different property names to refer
+ * to equivalent data. For example, ActionScheduler_IntervalSchedule::start_timestamp
+ * was the same as ActionScheduler_SimpleSchedule::timestamp. Action Scheduler 3.0.0
+ * aligned properties and property names for better inheritance. To guard against the
+ * scheduled date for single actions always being seen as "now" if downgrading to
+ * Action Scheduler < 3.0.0, we need to also store the data with the old property names
+ * so if it's unserialized in AS < 3.0, the schedule doesn't end up with a null recurrence.
+ *
+ * @return array
+ */
+ public function __sleep() {
+
+ $sleep_params = parent::__sleep();
+
+ $this->timestamp = $this->scheduled_timestamp;
+
+ return array_merge(
+ $sleep_params,
+ array(
+ 'timestamp',
+ )
+ );
+ }
+
+ /**
+ * Unserialize recurring schedules serialized/stored prior to AS 3.0.0
+ *
+ * Prior to Action Scheduler 3.0.0, schedules used different property names to refer
+ * to equivalent data. For example, ActionScheduler_IntervalSchedule::start_timestamp
+ * was the same as ActionScheduler_SimpleSchedule::timestamp. Action Scheduler 3.0.0
+ * aligned properties and property names for better inheritance. To maintain backward
+ * compatibility with schedules serialized and stored prior to 3.0, we need to correctly
+ * map the old property names with matching visibility.
+ */
+ public function __wakeup() {
+
+ if ( is_null( $this->scheduled_timestamp ) && ! is_null( $this->timestamp ) ) {
+ $this->scheduled_timestamp = $this->timestamp;
+ unset( $this->timestamp );
+ }
+ parent::__wakeup();
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/schema/ActionScheduler_LoggerSchema.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/schema/ActionScheduler_LoggerSchema.php
new file mode 100755
index 00000000..27e1c7ff
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/schema/ActionScheduler_LoggerSchema.php
@@ -0,0 +1,101 @@
+tables = array(
+ self::LOG_TABLE,
+ );
+ }
+
+ /**
+ * Performs additional setup work required to support this schema.
+ */
+ public function init() {
+ add_action( 'action_scheduler_before_schema_update', array( $this, 'update_schema_3_0' ), 10, 2 );
+ }
+
+ /**
+ * Get table definition.
+ *
+ * @param string $table Table name.
+ */
+ protected function get_table_definition( $table ) {
+ global $wpdb;
+ $table_name = $wpdb->$table;
+ $charset_collate = $wpdb->get_charset_collate();
+ switch ( $table ) {
+
+ case self::LOG_TABLE:
+ $default_date = ActionScheduler_StoreSchema::DEFAULT_DATE;
+ return "CREATE TABLE $table_name (
+ log_id bigint(20) unsigned NOT NULL auto_increment,
+ action_id bigint(20) unsigned NOT NULL,
+ message text NOT NULL,
+ log_date_gmt datetime NULL default '{$default_date}',
+ log_date_local datetime NULL default '{$default_date}',
+ PRIMARY KEY (log_id),
+ KEY action_id (action_id),
+ KEY log_date_gmt (log_date_gmt)
+ ) $charset_collate";
+
+ default:
+ return '';
+ }
+ }
+
+ /**
+ * Update the logs table schema, allowing datetime fields to be NULL.
+ *
+ * This is needed because the NOT NULL constraint causes a conflict with some versions of MySQL
+ * configured with sql_mode=NO_ZERO_DATE, which can for instance lead to tables not being created.
+ *
+ * Most other schema updates happen via ActionScheduler_Abstract_Schema::update_table(), however
+ * that method relies on dbDelta() and this change is not possible when using that function.
+ *
+ * @param string $table Name of table being updated.
+ * @param string $db_version The existing schema version of the table.
+ */
+ public function update_schema_3_0( $table, $db_version ) {
+ global $wpdb;
+
+ if ( 'actionscheduler_logs' !== $table || version_compare( $db_version, '3', '>=' ) ) {
+ return;
+ }
+
+ // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
+ $table_name = $wpdb->prefix . 'actionscheduler_logs';
+ $table_list = $wpdb->get_col( "SHOW TABLES LIKE '{$table_name}'" );
+ $default_date = ActionScheduler_StoreSchema::DEFAULT_DATE;
+
+ if ( ! empty( $table_list ) ) {
+ $query = "
+ ALTER TABLE {$table_name}
+ MODIFY COLUMN log_date_gmt datetime NULL default '{$default_date}',
+ MODIFY COLUMN log_date_local datetime NULL default '{$default_date}'
+ ";
+ $wpdb->query( $query ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
+ }
+ // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/schema/ActionScheduler_StoreSchema.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/schema/ActionScheduler_StoreSchema.php
new file mode 100755
index 00000000..e1d073f5
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/classes/schema/ActionScheduler_StoreSchema.php
@@ -0,0 +1,145 @@
+tables = array(
+ self::ACTIONS_TABLE,
+ self::CLAIMS_TABLE,
+ self::GROUPS_TABLE,
+ );
+ }
+
+ /**
+ * Performs additional setup work required to support this schema.
+ */
+ public function init() {
+ add_action( 'action_scheduler_before_schema_update', array( $this, 'update_schema_5_0' ), 10, 2 );
+ }
+
+ /**
+ * Get table definition.
+ *
+ * @param string $table Table name.
+ */
+ protected function get_table_definition( $table ) {
+ global $wpdb;
+ $table_name = $wpdb->$table;
+ $charset_collate = $wpdb->get_charset_collate();
+ $default_date = self::DEFAULT_DATE;
+ // phpcs:ignore Squiz.PHP.CommentedOutCode
+ $max_index_length = 191; // @see wp_get_db_schema()
+
+ $hook_status_scheduled_date_gmt_max_index_length = $max_index_length - 20 - 8; // - status, - scheduled_date_gmt
+
+ switch ( $table ) {
+
+ case self::ACTIONS_TABLE:
+ return "CREATE TABLE {$table_name} (
+ action_id bigint(20) unsigned NOT NULL auto_increment,
+ hook varchar(191) NOT NULL,
+ status varchar(20) NOT NULL,
+ scheduled_date_gmt datetime NULL default '{$default_date}',
+ scheduled_date_local datetime NULL default '{$default_date}',
+ priority tinyint unsigned NOT NULL default '10',
+ args varchar($max_index_length),
+ schedule longtext,
+ group_id bigint(20) unsigned NOT NULL default '0',
+ attempts int(11) NOT NULL default '0',
+ last_attempt_gmt datetime NULL default '{$default_date}',
+ last_attempt_local datetime NULL default '{$default_date}',
+ claim_id bigint(20) unsigned NOT NULL default '0',
+ extended_args varchar(8000) DEFAULT NULL,
+ PRIMARY KEY (action_id),
+ KEY hook_status_scheduled_date_gmt (hook($hook_status_scheduled_date_gmt_max_index_length), status, scheduled_date_gmt),
+ KEY status_scheduled_date_gmt (status, scheduled_date_gmt),
+ KEY scheduled_date_gmt (scheduled_date_gmt),
+ KEY args (args($max_index_length)),
+ KEY group_id (group_id),
+ KEY last_attempt_gmt (last_attempt_gmt),
+ KEY `claim_id_status_priority_scheduled_date_gmt` (`claim_id`,`status`,`priority`,`scheduled_date_gmt`),
+ KEY `status_last_attempt_gmt` (`status`,`last_attempt_gmt`),
+ KEY `status_claim_id` (`status`,`claim_id`)
+ ) $charset_collate";
+
+ case self::CLAIMS_TABLE:
+ return "CREATE TABLE {$table_name} (
+ claim_id bigint(20) unsigned NOT NULL auto_increment,
+ date_created_gmt datetime NULL default '{$default_date}',
+ PRIMARY KEY (claim_id),
+ KEY date_created_gmt (date_created_gmt)
+ ) $charset_collate";
+
+ case self::GROUPS_TABLE:
+ return "CREATE TABLE {$table_name} (
+ group_id bigint(20) unsigned NOT NULL auto_increment,
+ slug varchar(255) NOT NULL,
+ PRIMARY KEY (group_id),
+ KEY slug (slug($max_index_length))
+ ) $charset_collate";
+
+ default:
+ return '';
+ }
+ }
+
+ /**
+ * Update the actions table schema, allowing datetime fields to be NULL.
+ *
+ * This is needed because the NOT NULL constraint causes a conflict with some versions of MySQL
+ * configured with sql_mode=NO_ZERO_DATE, which can for instance lead to tables not being created.
+ *
+ * Most other schema updates happen via ActionScheduler_Abstract_Schema::update_table(), however
+ * that method relies on dbDelta() and this change is not possible when using that function.
+ *
+ * @param string $table Name of table being updated.
+ * @param string $db_version The existing schema version of the table.
+ */
+ public function update_schema_5_0( $table, $db_version ) {
+ global $wpdb;
+
+ if ( 'actionscheduler_actions' !== $table || version_compare( $db_version, '5', '>=' ) ) {
+ return;
+ }
+
+ // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
+ $table_name = $wpdb->prefix . 'actionscheduler_actions';
+ $table_list = $wpdb->get_col( "SHOW TABLES LIKE '{$table_name}'" );
+ $default_date = self::DEFAULT_DATE;
+
+ if ( ! empty( $table_list ) ) {
+ $query = "
+ ALTER TABLE {$table_name}
+ MODIFY COLUMN scheduled_date_gmt datetime NULL default '{$default_date}',
+ MODIFY COLUMN scheduled_date_local datetime NULL default '{$default_date}',
+ MODIFY COLUMN last_attempt_gmt datetime NULL default '{$default_date}',
+ MODIFY COLUMN last_attempt_local datetime NULL default '{$default_date}'
+ ";
+ $wpdb->query( $query ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
+ }
+ // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/deprecated/ActionScheduler_Abstract_QueueRunner_Deprecated.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/deprecated/ActionScheduler_Abstract_QueueRunner_Deprecated.php
new file mode 100755
index 00000000..e24ddca1
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/deprecated/ActionScheduler_Abstract_QueueRunner_Deprecated.php
@@ -0,0 +1,27 @@
+get_date();
+ $replacement_method = 'get_date()';
+ } else {
+ $return_value = $this->get_next( $after );
+ $replacement_method = 'get_next( $after )';
+ }
+
+ _deprecated_function( __METHOD__, '3.0.0', __CLASS__ . '::' . $replacement_method ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
+
+ return $return_value;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/deprecated/ActionScheduler_Store_Deprecated.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/deprecated/ActionScheduler_Store_Deprecated.php
new file mode 100755
index 00000000..02dc8b7c
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/deprecated/ActionScheduler_Store_Deprecated.php
@@ -0,0 +1,50 @@
+mark_failure( $action_id );
+ }
+
+ /**
+ * Add base hooks
+ *
+ * @since 2.2.6
+ */
+ protected static function hook() {
+ _deprecated_function( __METHOD__, '3.0.0' );
+ }
+
+ /**
+ * Remove base hooks
+ *
+ * @since 2.2.6
+ */
+ protected static function unhook() {
+ _deprecated_function( __METHOD__, '3.0.0' );
+ }
+
+ /**
+ * Get the site's local time.
+ *
+ * @deprecated 2.1.0
+ * @return DateTimeZone
+ */
+ protected function get_local_timezone() {
+ _deprecated_function( __FUNCTION__, '2.1.0', 'ActionScheduler_TimezoneHelper::set_local_timezone()' );
+ return ActionScheduler_TimezoneHelper::get_local_timezone();
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/deprecated/functions.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/deprecated/functions.php
new file mode 100755
index 00000000..76ac0195
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/deprecated/functions.php
@@ -0,0 +1,129 @@
+ '' - the name of the action that will be triggered
+ * 'args' => NULL - the args array that will be passed with the action
+ * 'date' => NULL - the scheduled date of the action. Expects a DateTime object, a unix timestamp, or a string that can parsed with strtotime(). Used in UTC timezone.
+ * 'date_compare' => '<=' - operator for testing "date". accepted values are '!=', '>', '>=', '<', '<=', '='
+ * 'modified' => NULL - the date the action was last updated. Expects a DateTime object, a unix timestamp, or a string that can parsed with strtotime(). Used in UTC timezone.
+ * 'modified_compare' => '<=' - operator for testing "modified". accepted values are '!=', '>', '>=', '<', '<=', '='
+ * 'group' => '' - the group the action belongs to
+ * 'status' => '' - ActionScheduler_Store::STATUS_COMPLETE or ActionScheduler_Store::STATUS_PENDING
+ * 'claimed' => NULL - TRUE to find claimed actions, FALSE to find unclaimed actions, a string to find a specific claim ID
+ * 'per_page' => 5 - Number of results to return
+ * 'offset' => 0
+ * 'orderby' => 'date' - accepted values are 'hook', 'group', 'modified', or 'date'
+ * 'order' => 'ASC'.
+ * @param string $return_format OBJECT, ARRAY_A, or ids.
+ *
+ * @deprecated 2.1.0
+ *
+ * @return array
+ */
+function wc_get_scheduled_actions( $args = array(), $return_format = OBJECT ) {
+ _deprecated_function( __FUNCTION__, '2.1.0', 'as_get_scheduled_actions()' );
+ return as_get_scheduled_actions( $args, $return_format );
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/functions.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/functions.php
new file mode 100755
index 00000000..d78c23ab
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/functions.php
@@ -0,0 +1,513 @@
+create(
+ array(
+ 'type' => 'async',
+ 'hook' => $hook,
+ 'arguments' => $args,
+ 'group' => $group,
+ 'unique' => $unique,
+ 'priority' => $priority,
+ )
+ );
+}
+
+/**
+ * Schedule an action to run one time
+ *
+ * @param int $timestamp When the job will run.
+ * @param string $hook The hook to trigger.
+ * @param array $args Arguments to pass when the hook triggers.
+ * @param string $group The group to assign this job to.
+ * @param bool $unique Whether the action should be unique. It will not be scheduled if another pending or running action has the same hook and group parameters.
+ * @param int $priority Lower values take precedence over higher values. Defaults to 10, with acceptable values falling in the range 0-255.
+ *
+ * @return int The action ID. Zero if there was an error scheduling the action.
+ */
+function as_schedule_single_action( $timestamp, $hook, $args = array(), $group = '', $unique = false, $priority = 10 ) {
+ if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
+ return 0;
+ }
+
+ /**
+ * Provides an opportunity to short-circuit the default process for enqueuing single
+ * actions.
+ *
+ * Returning a value other than null from the filter will short-circuit the normal
+ * process. The expectation in such a scenario is that callbacks will return an integer
+ * representing the scheduled action ID (scheduled using some alternative process) or else
+ * zero.
+ *
+ * @param int|null $pre_option The value to return instead of the option value.
+ * @param int $timestamp When the action will run.
+ * @param string $hook Action hook.
+ * @param array $args Action arguments.
+ * @param string $group Action group.
+ * @param int $priorities Action priority.
+ * @param bool $unique Unique action.
+ */
+ $pre = apply_filters( 'pre_as_schedule_single_action', null, $timestamp, $hook, $args, $group, $priority, $unique );
+ if ( null !== $pre ) {
+ return is_int( $pre ) ? $pre : 0;
+ }
+
+ return ActionScheduler::factory()->create(
+ array(
+ 'type' => 'single',
+ 'hook' => $hook,
+ 'arguments' => $args,
+ 'when' => $timestamp,
+ 'group' => $group,
+ 'unique' => $unique,
+ 'priority' => $priority,
+ )
+ );
+}
+
+/**
+ * Schedule a recurring action
+ *
+ * @param int $timestamp When the first instance of the job will run.
+ * @param int $interval_in_seconds How long to wait between runs.
+ * @param string $hook The hook to trigger.
+ * @param array $args Arguments to pass when the hook triggers.
+ * @param string $group The group to assign this job to.
+ * @param bool $unique Whether the action should be unique. It will not be scheduled if another pending or running action has the same hook and group parameters.
+ * @param int $priority Lower values take precedence over higher values. Defaults to 10, with acceptable values falling in the range 0-255.
+ *
+ * @return int The action ID. Zero if there was an error scheduling the action.
+ */
+function as_schedule_recurring_action( $timestamp, $interval_in_seconds, $hook, $args = array(), $group = '', $unique = false, $priority = 10 ) {
+ if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
+ return 0;
+ }
+
+ $interval = (int) $interval_in_seconds;
+
+ // We expect an integer and allow it to be passed using float and string types, but otherwise
+ // should reject unexpected values.
+ // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
+ if ( ! is_numeric( $interval_in_seconds ) || $interval_in_seconds != $interval ) {
+ _doing_it_wrong(
+ __METHOD__,
+ sprintf(
+ /* translators: 1: provided value 2: provided type. */
+ esc_html__( 'An integer was expected but "%1$s" (%2$s) was received.', 'action-scheduler' ),
+ esc_html( $interval_in_seconds ),
+ esc_html( gettype( $interval_in_seconds ) )
+ ),
+ '3.6.0'
+ );
+
+ return 0;
+ }
+
+ /**
+ * Provides an opportunity to short-circuit the default process for enqueuing recurring
+ * actions.
+ *
+ * Returning a value other than null from the filter will short-circuit the normal
+ * process. The expectation in such a scenario is that callbacks will return an integer
+ * representing the scheduled action ID (scheduled using some alternative process) or else
+ * zero.
+ *
+ * @param int|null $pre_option The value to return instead of the option value.
+ * @param int $timestamp When the action will run.
+ * @param int $interval_in_seconds How long to wait between runs.
+ * @param string $hook Action hook.
+ * @param array $args Action arguments.
+ * @param string $group Action group.
+ * @param int $priority Action priority.
+ * @param bool $unique Unique action.
+ */
+ $pre = apply_filters( 'pre_as_schedule_recurring_action', null, $timestamp, $interval_in_seconds, $hook, $args, $group, $priority, $unique );
+ if ( null !== $pre ) {
+ return is_int( $pre ) ? $pre : 0;
+ }
+
+ return ActionScheduler::factory()->create(
+ array(
+ 'type' => 'recurring',
+ 'hook' => $hook,
+ 'arguments' => $args,
+ 'when' => $timestamp,
+ 'pattern' => $interval_in_seconds,
+ 'group' => $group,
+ 'unique' => $unique,
+ 'priority' => $priority,
+ )
+ );
+}
+
+/**
+ * Schedule an action that recurs on a cron-like schedule.
+ *
+ * @param int $timestamp The first instance of the action will be scheduled
+ * to run at a time calculated after this timestamp matching the cron
+ * expression. This can be used to delay the first instance of the action.
+ * @param string $schedule A cron-link schedule string.
+ * @see http://en.wikipedia.org/wiki/Cron
+ * * * * * * *
+ * ⬠⬠⬠⬠⬠ā¬
+ * | | | | | |
+ * | | | | | + year [optional]
+ * | | | | +----- day of week (0 - 7) (Sunday=0 or 7)
+ * | | | +---------- month (1 - 12)
+ * | | +--------------- day of month (1 - 31)
+ * | +-------------------- hour (0 - 23)
+ * +------------------------- min (0 - 59)
+ * @param string $hook The hook to trigger.
+ * @param array $args Arguments to pass when the hook triggers.
+ * @param string $group The group to assign this job to.
+ * @param bool $unique Whether the action should be unique. It will not be scheduled if another pending or running action has the same hook and group parameters.
+ * @param int $priority Lower values take precedence over higher values. Defaults to 10, with acceptable values falling in the range 0-255.
+ *
+ * @return int The action ID. Zero if there was an error scheduling the action.
+ */
+function as_schedule_cron_action( $timestamp, $schedule, $hook, $args = array(), $group = '', $unique = false, $priority = 10 ) {
+ if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
+ return 0;
+ }
+
+ /**
+ * Provides an opportunity to short-circuit the default process for enqueuing cron
+ * actions.
+ *
+ * Returning a value other than null from the filter will short-circuit the normal
+ * process. The expectation in such a scenario is that callbacks will return an integer
+ * representing the scheduled action ID (scheduled using some alternative process) or else
+ * zero.
+ *
+ * @param int|null $pre_option The value to return instead of the option value.
+ * @param int $timestamp When the action will run.
+ * @param string $schedule Cron-like schedule string.
+ * @param string $hook Action hook.
+ * @param array $args Action arguments.
+ * @param string $group Action group.
+ * @param int $priority Action priority.
+ * @param bool $unique Unique action.
+ */
+ $pre = apply_filters( 'pre_as_schedule_cron_action', null, $timestamp, $schedule, $hook, $args, $group, $priority, $unique );
+ if ( null !== $pre ) {
+ return is_int( $pre ) ? $pre : 0;
+ }
+
+ return ActionScheduler::factory()->create(
+ array(
+ 'type' => 'cron',
+ 'hook' => $hook,
+ 'arguments' => $args,
+ 'when' => $timestamp,
+ 'pattern' => $schedule,
+ 'group' => $group,
+ 'unique' => $unique,
+ 'priority' => $priority,
+ )
+ );
+}
+
+/**
+ * Cancel the next occurrence of a scheduled action.
+ *
+ * While only the next instance of a recurring or cron action is unscheduled by this method, that will also prevent
+ * all future instances of that recurring or cron action from being run. Recurring and cron actions are scheduled in
+ * a sequence instead of all being scheduled at once. Each successive occurrence of a recurring action is scheduled
+ * only after the former action is run. If the next instance is never run, because it's unscheduled by this function,
+ * then the following instance will never be scheduled (or exist), which is effectively the same as being unscheduled
+ * by this method also.
+ *
+ * @param string $hook The hook that the job will trigger.
+ * @param array $args Args that would have been passed to the job.
+ * @param string $group The group the job is assigned to.
+ *
+ * @return int|null The scheduled action ID if a scheduled action was found, or null if no matching action found.
+ */
+function as_unschedule_action( $hook, $args = array(), $group = '' ) {
+ if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
+ return 0;
+ }
+ $params = array(
+ 'hook' => $hook,
+ 'status' => ActionScheduler_Store::STATUS_PENDING,
+ 'orderby' => 'date',
+ 'order' => 'ASC',
+ 'group' => $group,
+ );
+ if ( is_array( $args ) ) {
+ $params['args'] = $args;
+ }
+
+ $action_id = ActionScheduler::store()->query_action( $params );
+
+ if ( $action_id ) {
+ try {
+ ActionScheduler::store()->cancel_action( $action_id );
+ } catch ( Exception $exception ) {
+ ActionScheduler::logger()->log(
+ $action_id,
+ sprintf(
+ /* translators: %1$s is the name of the hook to be cancelled, %2$s is the exception message. */
+ __( 'Caught exception while cancelling action "%1$s": %2$s', 'action-scheduler' ),
+ $hook,
+ $exception->getMessage()
+ )
+ );
+
+ $action_id = null;
+ }
+ }
+
+ return $action_id;
+}
+
+/**
+ * Cancel all occurrences of a scheduled action.
+ *
+ * @param string $hook The hook that the job will trigger.
+ * @param array $args Args that would have been passed to the job.
+ * @param string $group The group the job is assigned to.
+ */
+function as_unschedule_all_actions( $hook, $args = array(), $group = '' ) {
+ if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
+ return;
+ }
+ if ( empty( $args ) ) {
+ if ( ! empty( $hook ) && empty( $group ) ) {
+ ActionScheduler_Store::instance()->cancel_actions_by_hook( $hook );
+ return;
+ }
+ if ( ! empty( $group ) && empty( $hook ) ) {
+ ActionScheduler_Store::instance()->cancel_actions_by_group( $group );
+ return;
+ }
+ }
+ do {
+ $unscheduled_action = as_unschedule_action( $hook, $args, $group );
+ } while ( ! empty( $unscheduled_action ) );
+}
+
+/**
+ * Check if there is an existing action in the queue with a given hook, args and group combination.
+ *
+ * An action in the queue could be pending, in-progress or async. If the is pending for a time in
+ * future, its scheduled date will be returned as a timestamp. If it is currently being run, or an
+ * async action sitting in the queue waiting to be processed, in which case boolean true will be
+ * returned. Or there may be no async, in-progress or pending action for this hook, in which case,
+ * boolean false will be the return value.
+ *
+ * @param string $hook Name of the hook to search for.
+ * @param array $args Arguments of the action to be searched.
+ * @param string $group Group of the action to be searched.
+ *
+ * @return int|bool The timestamp for the next occurrence of a pending scheduled action, true for an async or in-progress action or false if there is no matching action.
+ */
+function as_next_scheduled_action( $hook, $args = null, $group = '' ) {
+ if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
+ return false;
+ }
+
+ $params = array(
+ 'hook' => $hook,
+ 'orderby' => 'date',
+ 'order' => 'ASC',
+ 'group' => $group,
+ );
+
+ if ( is_array( $args ) ) {
+ $params['args'] = $args;
+ }
+
+ $params['status'] = ActionScheduler_Store::STATUS_RUNNING;
+ $action_id = ActionScheduler::store()->query_action( $params );
+ if ( $action_id ) {
+ return true;
+ }
+
+ $params['status'] = ActionScheduler_Store::STATUS_PENDING;
+ $action_id = ActionScheduler::store()->query_action( $params );
+ if ( null === $action_id ) {
+ return false;
+ }
+
+ $action = ActionScheduler::store()->fetch_action( $action_id );
+ $scheduled_date = $action->get_schedule()->get_date();
+ if ( $scheduled_date ) {
+ return (int) $scheduled_date->format( 'U' );
+ } elseif ( null === $scheduled_date ) { // pending async action with NullSchedule.
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * Check if there is a scheduled action in the queue but more efficiently than as_next_scheduled_action().
+ *
+ * It's recommended to use this function when you need to know whether a specific action is currently scheduled
+ * (pending or in-progress).
+ *
+ * @since 3.3.0
+ *
+ * @param string $hook The hook of the action.
+ * @param array $args Args that have been passed to the action. Null will matches any args.
+ * @param string $group The group the job is assigned to.
+ *
+ * @return bool True if a matching action is pending or in-progress, false otherwise.
+ */
+function as_has_scheduled_action( $hook, $args = null, $group = '' ) {
+ if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
+ return false;
+ }
+
+ $query_args = array(
+ 'hook' => $hook,
+ 'status' => array( ActionScheduler_Store::STATUS_RUNNING, ActionScheduler_Store::STATUS_PENDING ),
+ 'group' => $group,
+ 'orderby' => 'none',
+ );
+
+ if ( null !== $args ) {
+ $query_args['args'] = $args;
+ }
+
+ $action_id = ActionScheduler::store()->query_action( $query_args );
+
+ return null !== $action_id;
+}
+
+/**
+ * Find scheduled actions
+ *
+ * @param array $args Possible arguments, with their default values.
+ * 'hook' => '' - the name of the action that will be triggered.
+ * 'args' => NULL - the args array that will be passed with the action.
+ * 'date' => NULL - the scheduled date of the action. Expects a DateTime object, a unix timestamp, or a string that can parsed with strtotime(). Used in UTC timezone.
+ * 'date_compare' => '<=' - operator for testing "date". accepted values are '!=', '>', '>=', '<', '<=', '='.
+ * 'modified' => NULL - the date the action was last updated. Expects a DateTime object, a unix timestamp, or a string that can parsed with strtotime(). Used in UTC timezone.
+ * 'modified_compare' => '<=' - operator for testing "modified". accepted values are '!=', '>', '>=', '<', '<=', '='.
+ * 'group' => '' - the group the action belongs to.
+ * 'status' => '' - ActionScheduler_Store::STATUS_COMPLETE or ActionScheduler_Store::STATUS_PENDING.
+ * 'claimed' => NULL - TRUE to find claimed actions, FALSE to find unclaimed actions, a string to find a specific claim ID.
+ * 'per_page' => 5 - Number of results to return.
+ * 'offset' => 0.
+ * 'orderby' => 'date' - accepted values are 'hook', 'group', 'modified', 'date' or 'none'.
+ * 'order' => 'ASC'.
+ *
+ * @param string $return_format OBJECT, ARRAY_A, or ids.
+ *
+ * @return array
+ */
+function as_get_scheduled_actions( $args = array(), $return_format = OBJECT ) {
+ if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
+ return array();
+ }
+ $store = ActionScheduler::store();
+ foreach ( array( 'date', 'modified' ) as $key ) {
+ if ( isset( $args[ $key ] ) ) {
+ $args[ $key ] = as_get_datetime_object( $args[ $key ] );
+ }
+ }
+ $ids = $store->query_actions( $args );
+
+ if ( 'ids' === $return_format || 'int' === $return_format ) {
+ return $ids;
+ }
+
+ $actions = array();
+ foreach ( $ids as $action_id ) {
+ $actions[ $action_id ] = $store->fetch_action( $action_id );
+ }
+
+ if ( ARRAY_A === $return_format ) {
+ foreach ( $actions as $action_id => $action_object ) {
+ $actions[ $action_id ] = get_object_vars( $action_object );
+ }
+ }
+
+ return $actions;
+}
+
+/**
+ * Helper function to create an instance of DateTime based on a given
+ * string and timezone. By default, will return the current date/time
+ * in the UTC timezone.
+ *
+ * Needed because new DateTime() called without an explicit timezone
+ * will create a date/time in PHP's timezone, but we need to have
+ * assurance that a date/time uses the right timezone (which we almost
+ * always want to be UTC), which means we need to always include the
+ * timezone when instantiating datetimes rather than leaving it up to
+ * the PHP default.
+ *
+ * @param mixed $date_string A date/time string. Valid formats are explained in http://php.net/manual/en/datetime.formats.php.
+ * @param string $timezone A timezone identifier, like UTC or Europe/Lisbon. The list of valid identifiers is available http://php.net/manual/en/timezones.php.
+ *
+ * @return ActionScheduler_DateTime
+ */
+function as_get_datetime_object( $date_string = null, $timezone = 'UTC' ) {
+ if ( is_object( $date_string ) && $date_string instanceof DateTime ) {
+ $date = new ActionScheduler_DateTime( $date_string->format( 'Y-m-d H:i:s' ), new DateTimeZone( $timezone ) );
+ } elseif ( is_numeric( $date_string ) ) {
+ $date = new ActionScheduler_DateTime( '@' . $date_string, new DateTimeZone( $timezone ) );
+ } else {
+ $date = new ActionScheduler_DateTime( null === $date_string ? 'now' : $date_string, new DateTimeZone( $timezone ) );
+ }
+ return $date;
+}
+
+/**
+ * Check if a specific feature is supported by the current version of Action Scheduler.
+ *
+ * @since 3.9.3
+ *
+ * @param string $feature The feature to check support for.
+ *
+ * @return bool True if the feature is supported, false otherwise.
+ */
+function as_supports( string $feature ): bool {
+ $supported_features = array( 'ensure_recurring_actions_hook' );
+
+ return in_array( $feature, $supported_features, true );
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/lib/WP_Async_Request.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/lib/WP_Async_Request.php
new file mode 100755
index 00000000..a40c80a1
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/lib/WP_Async_Request.php
@@ -0,0 +1,188 @@
+identifier = $this->prefix . '_' . $this->action;
+
+ add_action( 'wp_ajax_' . $this->identifier, array( $this, 'maybe_handle' ) );
+ add_action( 'wp_ajax_nopriv_' . $this->identifier, array( $this, 'maybe_handle' ) );
+ }
+
+ /**
+ * Set data used during the request
+ *
+ * @param array $data Data.
+ *
+ * @return $this
+ */
+ public function data( $data ) {
+ $this->data = $data;
+
+ return $this;
+ }
+
+ /**
+ * Dispatch the async request
+ *
+ * @return array|WP_Error
+ */
+ public function dispatch() {
+ $url = add_query_arg( $this->get_query_args(), $this->get_query_url() );
+ $args = $this->get_post_args();
+
+ return wp_remote_post( esc_url_raw( $url ), $args );
+ }
+
+ /**
+ * Get query args
+ *
+ * @return array
+ */
+ protected function get_query_args() {
+ if ( property_exists( $this, 'query_args' ) ) {
+ return $this->query_args;
+ }
+
+ $args = array(
+ 'action' => $this->identifier,
+ 'nonce' => wp_create_nonce( $this->identifier ),
+ );
+
+ /**
+ * Filters the post arguments used during an async request.
+ *
+ * @param array $url
+ */
+ return apply_filters( $this->identifier . '_query_args', $args );
+ }
+
+ /**
+ * Get query URL
+ *
+ * @return string
+ */
+ protected function get_query_url() {
+ if ( property_exists( $this, 'query_url' ) ) {
+ return $this->query_url;
+ }
+
+ $url = admin_url( 'admin-ajax.php' );
+
+ /**
+ * Filters the post arguments used during an async request.
+ *
+ * @param string $url
+ */
+ return apply_filters( $this->identifier . '_query_url', $url );
+ }
+
+ /**
+ * Get post args
+ *
+ * @return array
+ */
+ protected function get_post_args() {
+ if ( property_exists( $this, 'post_args' ) ) {
+ return $this->post_args;
+ }
+
+ $args = array(
+ 'timeout' => 0.01,
+ 'blocking' => false,
+ 'body' => $this->data,
+ 'cookies' => $_COOKIE,
+ 'sslverify' => apply_filters( 'https_local_ssl_verify', false ),
+ );
+
+ /**
+ * Filters the post arguments used during an async request.
+ *
+ * @param array $args
+ */
+ return apply_filters( $this->identifier . '_post_args', $args );
+ }
+
+ /**
+ * Maybe handle
+ *
+ * Check for correct nonce and pass to handler.
+ */
+ public function maybe_handle() {
+ // Don't lock up other requests while processing.
+ session_write_close();
+
+ check_ajax_referer( $this->identifier, 'nonce' );
+
+ $this->handle();
+
+ wp_die();
+ }
+
+ /**
+ * Handle
+ *
+ * Override this method to perform any actions required
+ * during the async request.
+ */
+ abstract protected function handle();
+
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/lib/cron-expression/CronExpression.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/lib/cron-expression/CronExpression.php
new file mode 100755
index 00000000..33040edd
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/lib/cron-expression/CronExpression.php
@@ -0,0 +1,318 @@
+
+ * @link http://en.wikipedia.org/wiki/Cron
+ */
+class CronExpression
+{
+ const MINUTE = 0;
+ const HOUR = 1;
+ const DAY = 2;
+ const MONTH = 3;
+ const WEEKDAY = 4;
+ const YEAR = 5;
+
+ /**
+ * @var array CRON expression parts
+ */
+ private $cronParts;
+
+ /**
+ * @var CronExpression_FieldFactory CRON field factory
+ */
+ private $fieldFactory;
+
+ /**
+ * @var array Order in which to test of cron parts
+ */
+ private static $order = array(self::YEAR, self::MONTH, self::DAY, self::WEEKDAY, self::HOUR, self::MINUTE);
+
+ /**
+ * Factory method to create a new CronExpression.
+ *
+ * @param string $expression The CRON expression to create. There are
+ * several special predefined values which can be used to substitute the
+ * CRON expression:
+ *
+ * @yearly, @annually) - Run once a year, midnight, Jan. 1 - 0 0 1 1 *
+ * @monthly - Run once a month, midnight, first of month - 0 0 1 * *
+ * @weekly - Run once a week, midnight on Sun - 0 0 * * 0
+ * @daily - Run once a day, midnight - 0 0 * * *
+ * @hourly - Run once an hour, first minute - 0 * * * *
+ *
+*@param CronExpression_FieldFactory $fieldFactory (optional) Field factory to use
+ *
+ * @return CronExpression
+ */
+ public static function factory($expression, ?CronExpression_FieldFactory $fieldFactory = null)
+ {
+ $mappings = array(
+ '@yearly' => '0 0 1 1 *',
+ '@annually' => '0 0 1 1 *',
+ '@monthly' => '0 0 1 * *',
+ '@weekly' => '0 0 * * 0',
+ '@daily' => '0 0 * * *',
+ '@hourly' => '0 * * * *'
+ );
+
+ if (isset($mappings[$expression])) {
+ $expression = $mappings[$expression];
+ }
+
+ return new self($expression, $fieldFactory ? $fieldFactory : new CronExpression_FieldFactory());
+ }
+
+ /**
+ * Parse a CRON expression
+ *
+ * @param string $expression CRON expression (e.g. '8 * * * *')
+ * @param CronExpression_FieldFactory $fieldFactory Factory to create cron fields
+ */
+ public function __construct($expression, CronExpression_FieldFactory $fieldFactory)
+ {
+ $this->fieldFactory = $fieldFactory;
+ $this->setExpression($expression);
+ }
+
+ /**
+ * Set or change the CRON expression
+ *
+ * @param string $value CRON expression (e.g. 8 * * * *)
+ *
+ * @return CronExpression
+ * @throws InvalidArgumentException if not a valid CRON expression
+ */
+ public function setExpression($value)
+ {
+ $this->cronParts = preg_split('/\s/', $value, -1, PREG_SPLIT_NO_EMPTY);
+ if (count($this->cronParts) < 5) {
+ throw new InvalidArgumentException(
+ $value . ' is not a valid CRON expression'
+ );
+ }
+
+ foreach ($this->cronParts as $position => $part) {
+ $this->setPart($position, $part);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Set part of the CRON expression
+ *
+ * @param int $position The position of the CRON expression to set
+ * @param string $value The value to set
+ *
+ * @return CronExpression
+ * @throws InvalidArgumentException if the value is not valid for the part
+ */
+ public function setPart($position, $value)
+ {
+ if (!$this->fieldFactory->getField($position)->validate($value)) {
+ throw new InvalidArgumentException(
+ 'Invalid CRON field value ' . $value . ' as position ' . $position
+ );
+ }
+
+ $this->cronParts[$position] = $value;
+
+ return $this;
+ }
+
+ /**
+ * Get a next run date relative to the current date or a specific date
+ *
+ * @param string|DateTime $currentTime (optional) Relative calculation date
+ * @param int $nth (optional) Number of matches to skip before returning a
+ * matching next run date. 0, the default, will return the current
+ * date and time if the next run date falls on the current date and
+ * time. Setting this value to 1 will skip the first match and go to
+ * the second match. Setting this value to 2 will skip the first 2
+ * matches and so on.
+ * @param bool $allowCurrentDate (optional) Set to TRUE to return the
+ * current date if it matches the cron expression
+ *
+ * @return DateTime
+ * @throws RuntimeException on too many iterations
+ */
+ public function getNextRunDate($currentTime = 'now', $nth = 0, $allowCurrentDate = false)
+ {
+ return $this->getRunDate($currentTime, $nth, false, $allowCurrentDate);
+ }
+
+ /**
+ * Get a previous run date relative to the current date or a specific date
+ *
+ * @param string|DateTime $currentTime (optional) Relative calculation date
+ * @param int $nth (optional) Number of matches to skip before returning
+ * @param bool $allowCurrentDate (optional) Set to TRUE to return the
+ * current date if it matches the cron expression
+ *
+ * @return DateTime
+ * @throws RuntimeException on too many iterations
+ * @see CronExpression::getNextRunDate
+ */
+ public function getPreviousRunDate($currentTime = 'now', $nth = 0, $allowCurrentDate = false)
+ {
+ return $this->getRunDate($currentTime, $nth, true, $allowCurrentDate);
+ }
+
+ /**
+ * Get multiple run dates starting at the current date or a specific date
+ *
+ * @param int $total Set the total number of dates to calculate
+ * @param string|DateTime $currentTime (optional) Relative calculation date
+ * @param bool $invert (optional) Set to TRUE to retrieve previous dates
+ * @param bool $allowCurrentDate (optional) Set to TRUE to return the
+ * current date if it matches the cron expression
+ *
+ * @return array Returns an array of run dates
+ */
+ public function getMultipleRunDates($total, $currentTime = 'now', $invert = false, $allowCurrentDate = false)
+ {
+ $matches = array();
+ for ($i = 0; $i < max(0, $total); $i++) {
+ $matches[] = $this->getRunDate($currentTime, $i, $invert, $allowCurrentDate);
+ }
+
+ return $matches;
+ }
+
+ /**
+ * Get all or part of the CRON expression
+ *
+ * @param string $part (optional) Specify the part to retrieve or NULL to
+ * get the full cron schedule string.
+ *
+ * @return string|null Returns the CRON expression, a part of the
+ * CRON expression, or NULL if the part was specified but not found
+ */
+ public function getExpression($part = null)
+ {
+ if (null === $part) {
+ return implode(' ', $this->cronParts);
+ } elseif (array_key_exists($part, $this->cronParts)) {
+ return $this->cronParts[$part];
+ }
+
+ return null;
+ }
+
+ /**
+ * Helper method to output the full expression.
+ *
+ * @return string Full CRON expression
+ */
+ public function __toString()
+ {
+ return $this->getExpression();
+ }
+
+ /**
+ * Determine if the cron is due to run based on the current date or a
+ * specific date. This method assumes that the current number of
+ * seconds are irrelevant, and should be called once per minute.
+ *
+ * @param string|DateTime $currentTime (optional) Relative calculation date
+ *
+ * @return bool Returns TRUE if the cron is due to run or FALSE if not
+ */
+ public function isDue($currentTime = 'now')
+ {
+ if ('now' === $currentTime) {
+ $currentDate = date('Y-m-d H:i');
+ $currentTime = strtotime($currentDate);
+ } elseif ($currentTime instanceof DateTime) {
+ $currentDate = $currentTime->format('Y-m-d H:i');
+ $currentTime = strtotime($currentDate);
+ } else {
+ $currentTime = new DateTime($currentTime);
+ $currentTime->setTime($currentTime->format('H'), $currentTime->format('i'), 0);
+ $currentDate = $currentTime->format('Y-m-d H:i');
+ $currentTime = (int)($currentTime->getTimestamp());
+ }
+
+ return $this->getNextRunDate($currentDate, 0, true)->getTimestamp() == $currentTime;
+ }
+
+ /**
+ * Get the next or previous run date of the expression relative to a date
+ *
+ * @param string|DateTime $currentTime (optional) Relative calculation date
+ * @param int $nth (optional) Number of matches to skip before returning
+ * @param bool $invert (optional) Set to TRUE to go backwards in time
+ * @param bool $allowCurrentDate (optional) Set to TRUE to return the
+ * current date if it matches the cron expression
+ *
+ * @return DateTime
+ * @throws RuntimeException on too many iterations
+ */
+ protected function getRunDate($currentTime = null, $nth = 0, $invert = false, $allowCurrentDate = false)
+ {
+ if ($currentTime instanceof DateTime) {
+ $currentDate = $currentTime;
+ } else {
+ $currentDate = new DateTime($currentTime ? $currentTime : 'now');
+ $currentDate->setTimezone(new DateTimeZone(date_default_timezone_get()));
+ }
+
+ $currentDate->setTime($currentDate->format('H'), $currentDate->format('i'), 0);
+ $nextRun = clone $currentDate;
+ $nth = (int) $nth;
+
+ // Set a hard limit to bail on an impossible date
+ for ($i = 0; $i < 1000; $i++) {
+
+ foreach (self::$order as $position) {
+ $part = $this->getExpression($position);
+ if (null === $part) {
+ continue;
+ }
+
+ $satisfied = false;
+ // Get the field object used to validate this part
+ $field = $this->fieldFactory->getField($position);
+ // Check if this is singular or a list
+ if (strpos($part, ',') === false) {
+ $satisfied = $field->isSatisfiedBy($nextRun, $part);
+ } else {
+ foreach (array_map('trim', explode(',', $part)) as $listPart) {
+ if ($field->isSatisfiedBy($nextRun, $listPart)) {
+ $satisfied = true;
+ break;
+ }
+ }
+ }
+
+ // If the field is not satisfied, then start over
+ if (!$satisfied) {
+ $field->increment($nextRun, $invert);
+ continue 2;
+ }
+ }
+
+ // Skip this match if needed
+ if ((!$allowCurrentDate && $nextRun == $currentDate) || --$nth > -1) {
+ $this->fieldFactory->getField(0)->increment($nextRun, $invert);
+ continue;
+ }
+
+ return $nextRun;
+ }
+
+ // @codeCoverageIgnoreStart
+ throw new RuntimeException('Impossible CRON expression');
+ // @codeCoverageIgnoreEnd
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/lib/cron-expression/CronExpression_AbstractField.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/lib/cron-expression/CronExpression_AbstractField.php
new file mode 100755
index 00000000..f8d5c00a
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/lib/cron-expression/CronExpression_AbstractField.php
@@ -0,0 +1,100 @@
+
+ */
+abstract class CronExpression_AbstractField implements CronExpression_FieldInterface
+{
+ /**
+ * Check to see if a field is satisfied by a value
+ *
+ * @param string $dateValue Date value to check
+ * @param string $value Value to test
+ *
+ * @return bool
+ */
+ public function isSatisfied($dateValue, $value)
+ {
+ if ($this->isIncrementsOfRanges($value)) {
+ return $this->isInIncrementsOfRanges($dateValue, $value);
+ } elseif ($this->isRange($value)) {
+ return $this->isInRange($dateValue, $value);
+ }
+
+ return $value == '*' || $dateValue == $value;
+ }
+
+ /**
+ * Check if a value is a range
+ *
+ * @param string $value Value to test
+ *
+ * @return bool
+ */
+ public function isRange($value)
+ {
+ return strpos($value, '-') !== false;
+ }
+
+ /**
+ * Check if a value is an increments of ranges
+ *
+ * @param string $value Value to test
+ *
+ * @return bool
+ */
+ public function isIncrementsOfRanges($value)
+ {
+ return strpos($value, '/') !== false;
+ }
+
+ /**
+ * Test if a value is within a range
+ *
+ * @param string $dateValue Set date value
+ * @param string $value Value to test
+ *
+ * @return bool
+ */
+ public function isInRange($dateValue, $value)
+ {
+ $parts = array_map('trim', explode('-', $value, 2));
+
+ return $dateValue >= $parts[0] && $dateValue <= $parts[1];
+ }
+
+ /**
+ * Test if a value is within an increments of ranges (offset[-to]/step size)
+ *
+ * @param string $dateValue Set date value
+ * @param string $value Value to test
+ *
+ * @return bool
+ */
+ public function isInIncrementsOfRanges($dateValue, $value)
+ {
+ $parts = array_map('trim', explode('/', $value, 2));
+ $stepSize = isset($parts[1]) ? $parts[1] : 0;
+ if ($parts[0] == '*' || $parts[0] === '0') {
+ return (int) $dateValue % $stepSize == 0;
+ }
+
+ $range = explode('-', $parts[0], 2);
+ $offset = $range[0];
+ $to = isset($range[1]) ? $range[1] : $dateValue;
+ // Ensure that the date value is within the range
+ if ($dateValue < $offset || $dateValue > $to) {
+ return false;
+ }
+
+ for ($i = $offset; $i <= $to; $i+= $stepSize) {
+ if ($i == $dateValue) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/lib/cron-expression/CronExpression_DayOfMonthField.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/lib/cron-expression/CronExpression_DayOfMonthField.php
new file mode 100755
index 00000000..40c1d6c6
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/lib/cron-expression/CronExpression_DayOfMonthField.php
@@ -0,0 +1,110 @@
+
+ */
+class CronExpression_DayOfMonthField extends CronExpression_AbstractField
+{
+ /**
+ * Get the nearest day of the week for a given day in a month
+ *
+ * @param int $currentYear Current year
+ * @param int $currentMonth Current month
+ * @param int $targetDay Target day of the month
+ *
+ * @return DateTime Returns the nearest date
+ */
+ private static function getNearestWeekday($currentYear, $currentMonth, $targetDay)
+ {
+ $tday = str_pad($targetDay, 2, '0', STR_PAD_LEFT);
+ $target = new DateTime("$currentYear-$currentMonth-$tday");
+ $currentWeekday = (int) $target->format('N');
+
+ if ($currentWeekday < 6) {
+ return $target;
+ }
+
+ $lastDayOfMonth = $target->format('t');
+
+ foreach (array(-1, 1, -2, 2) as $i) {
+ $adjusted = $targetDay + $i;
+ if ($adjusted > 0 && $adjusted <= $lastDayOfMonth) {
+ $target->setDate($currentYear, $currentMonth, $adjusted);
+ if ($target->format('N') < 6 && $target->format('m') == $currentMonth) {
+ return $target;
+ }
+ }
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isSatisfiedBy(DateTime $date, $value)
+ {
+ // ? states that the field value is to be skipped
+ if ($value == '?') {
+ return true;
+ }
+
+ $fieldValue = $date->format('d');
+
+ // Check to see if this is the last day of the month
+ if ($value == 'L') {
+ return $fieldValue == $date->format('t');
+ }
+
+ // Check to see if this is the nearest weekday to a particular value
+ if (strpos($value, 'W')) {
+ // Parse the target day
+ $targetDay = substr($value, 0, strpos($value, 'W'));
+ // Find out if the current day is the nearest day of the week
+ return $date->format('j') == self::getNearestWeekday(
+ $date->format('Y'),
+ $date->format('m'),
+ $targetDay
+ )->format('j');
+ }
+
+ return $this->isSatisfied($date->format('d'), $value);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function increment(DateTime $date, $invert = false)
+ {
+ if ($invert) {
+ $date->modify('previous day');
+ $date->setTime(23, 59);
+ } else {
+ $date->modify('next day');
+ $date->setTime(0, 0);
+ }
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($value)
+ {
+ return (bool) preg_match('/[\*,\/\-\?LW0-9A-Za-z]+/', $value);
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/lib/cron-expression/CronExpression_DayOfWeekField.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/lib/cron-expression/CronExpression_DayOfWeekField.php
new file mode 100755
index 00000000..e9f68a7c
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/lib/cron-expression/CronExpression_DayOfWeekField.php
@@ -0,0 +1,124 @@
+
+ */
+class CronExpression_DayOfWeekField extends CronExpression_AbstractField
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function isSatisfiedBy(DateTime $date, $value)
+ {
+ if ($value == '?') {
+ return true;
+ }
+
+ // Convert text day of the week values to integers
+ $value = str_ireplace(
+ array('SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT'),
+ range(0, 6),
+ $value
+ );
+
+ $currentYear = $date->format('Y');
+ $currentMonth = $date->format('m');
+ $lastDayOfMonth = $date->format('t');
+
+ // Find out if this is the last specific weekday of the month
+ if (strpos($value, 'L')) {
+ $weekday = str_replace('7', '0', substr($value, 0, strpos($value, 'L')));
+ $tdate = clone $date;
+ $tdate->setDate($currentYear, $currentMonth, $lastDayOfMonth);
+ while ($tdate->format('w') != $weekday) {
+ $tdate->setDate($currentYear, $currentMonth, --$lastDayOfMonth);
+ }
+
+ return $date->format('j') == $lastDayOfMonth;
+ }
+
+ // Handle # hash tokens
+ if (strpos($value, '#')) {
+ list($weekday, $nth) = explode('#', $value);
+ // Validate the hash fields
+ if ($weekday < 1 || $weekday > 5) {
+ throw new InvalidArgumentException("Weekday must be a value between 1 and 5. {$weekday} given");
+ }
+ if ($nth > 5) {
+ throw new InvalidArgumentException('There are never more than 5 of a given weekday in a month');
+ }
+ // The current weekday must match the targeted weekday to proceed
+ if ($date->format('N') != $weekday) {
+ return false;
+ }
+
+ $tdate = clone $date;
+ $tdate->setDate($currentYear, $currentMonth, 1);
+ $dayCount = 0;
+ $currentDay = 1;
+ while ($currentDay < $lastDayOfMonth + 1) {
+ if ($tdate->format('N') == $weekday) {
+ if (++$dayCount >= $nth) {
+ break;
+ }
+ }
+ $tdate->setDate($currentYear, $currentMonth, ++$currentDay);
+ }
+
+ return $date->format('j') == $currentDay;
+ }
+
+ // Handle day of the week values
+ if (strpos($value, '-')) {
+ $parts = explode('-', $value);
+ if ($parts[0] == '7') {
+ $parts[0] = '0';
+ } elseif ($parts[1] == '0') {
+ $parts[1] = '7';
+ }
+ $value = implode('-', $parts);
+ }
+
+ // Test to see which Sunday to use -- 0 == 7 == Sunday
+ $format = in_array(7, str_split($value)) ? 'N' : 'w';
+ $fieldValue = $date->format($format);
+
+ return $this->isSatisfied($fieldValue, $value);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function increment(DateTime $date, $invert = false)
+ {
+ if ($invert) {
+ $date->modify('-1 day');
+ $date->setTime(23, 59, 0);
+ } else {
+ $date->modify('+1 day');
+ $date->setTime(0, 0, 0);
+ }
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($value)
+ {
+ return (bool) preg_match('/[\*,\/\-0-9A-Z]+/', $value);
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/lib/cron-expression/CronExpression_FieldFactory.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/lib/cron-expression/CronExpression_FieldFactory.php
new file mode 100755
index 00000000..556ba1a3
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/lib/cron-expression/CronExpression_FieldFactory.php
@@ -0,0 +1,55 @@
+
+ * @link http://en.wikipedia.org/wiki/Cron
+ */
+class CronExpression_FieldFactory
+{
+ /**
+ * @var array Cache of instantiated fields
+ */
+ private $fields = array();
+
+ /**
+ * Get an instance of a field object for a cron expression position
+ *
+ * @param int $position CRON expression position value to retrieve
+ *
+ * @return CronExpression_FieldInterface
+ * @throws InvalidArgumentException if a position is not valid
+ */
+ public function getField($position)
+ {
+ if (!isset($this->fields[$position])) {
+ switch ($position) {
+ case 0:
+ $this->fields[$position] = new CronExpression_MinutesField();
+ break;
+ case 1:
+ $this->fields[$position] = new CronExpression_HoursField();
+ break;
+ case 2:
+ $this->fields[$position] = new CronExpression_DayOfMonthField();
+ break;
+ case 3:
+ $this->fields[$position] = new CronExpression_MonthField();
+ break;
+ case 4:
+ $this->fields[$position] = new CronExpression_DayOfWeekField();
+ break;
+ case 5:
+ $this->fields[$position] = new CronExpression_YearField();
+ break;
+ default:
+ throw new InvalidArgumentException(
+ $position . ' is not a valid position'
+ );
+ }
+ }
+
+ return $this->fields[$position];
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/lib/cron-expression/CronExpression_FieldInterface.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/lib/cron-expression/CronExpression_FieldInterface.php
new file mode 100755
index 00000000..5d5109b7
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/lib/cron-expression/CronExpression_FieldInterface.php
@@ -0,0 +1,39 @@
+
+ */
+interface CronExpression_FieldInterface
+{
+ /**
+ * Check if the respective value of a DateTime field satisfies a CRON exp
+ *
+ * @param DateTime $date DateTime object to check
+ * @param string $value CRON expression to test against
+ *
+ * @return bool Returns TRUE if satisfied, FALSE otherwise
+ */
+ public function isSatisfiedBy(DateTime $date, $value);
+
+ /**
+ * When a CRON expression is not satisfied, this method is used to increment
+ * or decrement a DateTime object by the unit of the cron field
+ *
+ * @param DateTime $date DateTime object to change
+ * @param bool $invert (optional) Set to TRUE to decrement
+ *
+ * @return CronExpression_FieldInterface
+ */
+ public function increment(DateTime $date, $invert = false);
+
+ /**
+ * Validates a CRON expression for a given field
+ *
+ * @param string $value CRON expression value to validate
+ *
+ * @return bool Returns TRUE if valid, FALSE otherwise
+ */
+ public function validate($value);
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/lib/cron-expression/CronExpression_HoursField.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/lib/cron-expression/CronExpression_HoursField.php
new file mode 100755
index 00000000..088ca73c
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/lib/cron-expression/CronExpression_HoursField.php
@@ -0,0 +1,47 @@
+
+ */
+class CronExpression_HoursField extends CronExpression_AbstractField
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function isSatisfiedBy(DateTime $date, $value)
+ {
+ return $this->isSatisfied($date->format('H'), $value);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function increment(DateTime $date, $invert = false)
+ {
+ // Change timezone to UTC temporarily. This will
+ // allow us to go back or forwards and hour even
+ // if DST will be changed between the hours.
+ $timezone = $date->getTimezone();
+ $date->setTimezone(new DateTimeZone('UTC'));
+ if ($invert) {
+ $date->modify('-1 hour');
+ $date->setTime($date->format('H'), 59);
+ } else {
+ $date->modify('+1 hour');
+ $date->setTime($date->format('H'), 0);
+ }
+ $date->setTimezone($timezone);
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($value)
+ {
+ return (bool) preg_match('/[\*,\/\-0-9]+/', $value);
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/lib/cron-expression/CronExpression_MinutesField.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/lib/cron-expression/CronExpression_MinutesField.php
new file mode 100755
index 00000000..436acf2f
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/lib/cron-expression/CronExpression_MinutesField.php
@@ -0,0 +1,39 @@
+
+ */
+class CronExpression_MinutesField extends CronExpression_AbstractField
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function isSatisfiedBy(DateTime $date, $value)
+ {
+ return $this->isSatisfied($date->format('i'), $value);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function increment(DateTime $date, $invert = false)
+ {
+ if ($invert) {
+ $date->modify('-1 minute');
+ } else {
+ $date->modify('+1 minute');
+ }
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($value)
+ {
+ return (bool) preg_match('/[\*,\/\-0-9]+/', $value);
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/lib/cron-expression/CronExpression_MonthField.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/lib/cron-expression/CronExpression_MonthField.php
new file mode 100755
index 00000000..d3deb129
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/lib/cron-expression/CronExpression_MonthField.php
@@ -0,0 +1,55 @@
+
+ */
+class CronExpression_MonthField extends CronExpression_AbstractField
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function isSatisfiedBy(DateTime $date, $value)
+ {
+ // Convert text month values to integers
+ $value = str_ireplace(
+ array(
+ 'JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN',
+ 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC'
+ ),
+ range(1, 12),
+ $value
+ );
+
+ return $this->isSatisfied($date->format('m'), $value);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function increment(DateTime $date, $invert = false)
+ {
+ if ($invert) {
+ // $date->modify('last day of previous month'); // remove for php 5.2 compat
+ $date->modify('previous month');
+ $date->modify($date->format('Y-m-t'));
+ $date->setTime(23, 59);
+ } else {
+ //$date->modify('first day of next month'); // remove for php 5.2 compat
+ $date->modify('next month');
+ $date->modify($date->format('Y-m-01'));
+ $date->setTime(0, 0);
+ }
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($value)
+ {
+ return (bool) preg_match('/[\*,\/\-0-9A-Z]+/', $value);
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/lib/cron-expression/CronExpression_YearField.php b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/lib/cron-expression/CronExpression_YearField.php
new file mode 100755
index 00000000..f11562e4
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/lib/cron-expression/CronExpression_YearField.php
@@ -0,0 +1,43 @@
+
+ */
+class CronExpression_YearField extends CronExpression_AbstractField
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function isSatisfiedBy(DateTime $date, $value)
+ {
+ return $this->isSatisfied($date->format('Y'), $value);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function increment(DateTime $date, $invert = false)
+ {
+ if ($invert) {
+ $date->modify('-1 year');
+ $date->setDate($date->format('Y'), 12, 31);
+ $date->setTime(23, 59, 0);
+ } else {
+ $date->modify('+1 year');
+ $date->setDate($date->format('Y'), 1, 1);
+ $date->setTime(0, 0, 0);
+ }
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($value)
+ {
+ return (bool) preg_match('/[\*,\/\-0-9]+/', $value);
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/lib/cron-expression/LICENSE b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/lib/cron-expression/LICENSE
new file mode 100755
index 00000000..c6d88ac6
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/lib/cron-expression/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2011 Michael Dowling and contributors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/license.txt b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/license.txt
new file mode 100755
index 00000000..f288702d
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/license.txt
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/readme.txt b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/readme.txt
new file mode 100755
index 00000000..8a6aa0a8
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor/woocommerce/action-scheduler/readme.txt
@@ -0,0 +1,244 @@
+=== Action Scheduler ===
+Contributors: Automattic, wpmuguru, claudiosanches, peterfabian1000, vedjain, jamosova, obliviousharmony, konamiman, sadowski, royho, barryhughes-1
+Tags: scheduler, cron
+Stable tag: 3.9.3
+License: GPLv3
+Requires at least: 6.5
+Tested up to: 6.8
+Requires PHP: 7.2
+
+Action Scheduler - Job Queue for WordPress
+
+== Description ==
+
+Action Scheduler is a scalable, traceable job queue for background processing large sets of actions in WordPress. It's specially designed to be distributed in WordPress plugins.
+
+Action Scheduler works by triggering an action hook to run at some time in the future. Each hook can be scheduled with unique data, to allow callbacks to perform operations on that data. The hook can also be scheduled to run on one or more occasions.
+
+Think of it like an extension to `do_action()` which adds the ability to delay and repeat a hook.
+
+## Battle-Tested Background Processing
+
+Every month, Action Scheduler processes millions of payments for [Subscriptions](https://woocommerce.com/products/woocommerce-subscriptions/), webhooks for [WooCommerce](https://wordpress.org/plugins/woocommerce/), as well as emails and other events for a range of other plugins.
+
+It's been seen on live sites processing queues in excess of 50,000 jobs and doing resource intensive operations, like processing payments and creating orders, at a sustained rate of over 10,000 / hour without negatively impacting normal site operations.
+
+This is all on infrastructure and WordPress sites outside the control of the plugin author.
+
+If your plugin needs background processing, especially of large sets of tasks, Action Scheduler can help.
+
+## Learn More
+
+To learn more about how Action Scheduler works, and how to use it in your plugin, check out the docs on [ActionScheduler.org](https://actionscheduler.org).
+
+There you will find:
+
+* [Usage guide](https://actionscheduler.org/usage/): instructions on installing and using Action Scheduler
+* [WP CLI guide](https://actionscheduler.org/wp-cli/): instructions on running Action Scheduler at scale via WP CLI
+* [API Reference](https://actionscheduler.org/api/): complete reference guide for all API functions
+* [Administration Guide](https://actionscheduler.org/admin/): guide to managing scheduled actions via the administration screen
+* [Guide to Background Processing at Scale](https://actionscheduler.org/perf/): instructions for running Action Scheduler at scale via the default WP Cron queue runner
+
+## Credits
+
+Action Scheduler is developed and maintained by [Automattic](http://automattic.com/) with significant early development completed by [Flightless](https://flightless.us/).
+
+Collaboration is cool. We'd love to work with you to improve Action Scheduler. [Pull Requests](https://github.com/woocommerce/action-scheduler/pulls) welcome.
+
+== Changelog ==
+
+= 3.9.3 - 2025-07-15 =
+* Add hook 'action_scheduler_ensure_recurring_actions' specifically for scheduling recurring actions.
+* Assume an action is valid until proven otherwise.
+* Implement SKIP LOCKED during action claiming.
+* Import `get_flag_value()` from `WP_CLI\Utils` before using.
+* Make `$unique` available to all pre-creation/short-circuit hooks.
+* Make version/source information available via new class.
+* Only release claims on pending actions.
+* Tweak - WP 6.8 compatibility.
+* Update minimum supported php and phpunit versions.
+* Update readme.txt.
+* WP CLI get action command: correct parentheses/nesting of conditional checks.
+
+= 3.9.2 - 2025-02-03 =
+* Fixed fatal errors by moving version info methods to a new class and deprecating conflicting ones in ActionScheduler_Versions
+
+= 3.9.1 - 2025-01-21 =
+* A number of new WP CLI commands have been added, making it easier to manage actions in the terminal and from scripts.
+* New wp action-scheduler source command to help determine how Action Scheduler is being loaded.
+* Additional information about the active instance of Action Scheduler is now available in the Help pull-down drawer.
+* Make some other nullable parameters explicitly nullable.
+* Set option value to `no` rather than deleting.
+
+= 3.9.0 - 2024-11-14 =
+* Minimum required version of PHP is now 7.1.
+* Performance improvements for the `as_pending_actions_due()` function.
+* Existing filter hook `action_scheduler_claim_actions_order_by` enhanced to provide callbacks with additional information.
+* Improved compatibility with PHP 8.4, specifically by making implicitly nullable parameters explicitly nullable.
+* A large number of coding standards-enhancements, to help reduce friction when submitting plugins to marketplaces and plugin directories. Special props @crstauf for this effort.
+* Minor documentation tweaks and improvements.
+
+= 3.8.2 - 2024-09-12 =
+* Add missing parameter to the `pre_as_enqueue_async_action` hook.
+* Bump minimum PHP version to 7.0.
+* Bump minimum WordPress version to 6.4.
+* Make the batch size adjustable during processing.
+
+= 3.8.1 - 2024-06-20 =
+* Fix typos.
+* Improve the messaging in our unidentified action exceptions.
+
+= 3.8.0 - 2024-05-22 =
+* Documentation - Fixed typos in perf.md.
+* Update - We now require WordPress 6.3 or higher.
+* Update - We now require PHP 7.0 or higher.
+
+= 3.7.4 - 2024-04-05 =
+* Give a clear description of how the $unique parameter works.
+* Preserve the tab field if set.
+* Tweak - WP 6.5 compatibility.
+
+= 3.7.3 - 2024-03-20 =
+* Do not iterate over all of GET when building form in list table.
+* Fix a few issues reported by PCP (Plugin Check Plugin).
+* Try to save actions as unique even when the store doesn't support it.
+* Tweak - WP 6.4 compatibility.
+* Update "Tested up to" tag to WordPress 6.5.
+* update version in package-lock.json.
+
+= 3.7.2 - 2024-02-14 =
+* No longer user variables in `_n()` translation function.
+
+= 3.7.1 - 2023-12-13 =
+* update semver to 5.7.2 because of a security vulnerability in 5.7.1.
+
+= 3.7.0 - 2023-11-20 =
+* Important: starting with this release, Action Scheduler follows an L-2 version policy (WordPress, and consequently PHP).
+* Add extended indexes for hook_status_scheduled_date_gmt and status_scheduled_date_gmt.
+* Catch and log exceptions thrown when actions can't be created, e.g. under a corrupt database schema.
+* Tweak - WP 6.4 compatibility.
+* Update unit tests for upcoming dependency version policy.
+* make sure hook action_scheduler_failed_execution can access original exception object.
+* mention dependency version policy in usage.md.
+
+= 3.6.4 - 2023-10-11 =
+* Performance improvements when bulk cancelling actions.
+* Dev-related fixes.
+
+= 3.6.3 - 2023-09-13 =
+* Use `_doing_it_wrong` in initialization check.
+
+= 3.6.2 - 2023-08-09 =
+* Add guidance about passing arguments.
+* Atomic option locking.
+* Improve bulk delete handling.
+* Include database error in the exception message.
+* Tweak - WP 6.3 compatibility.
+
+= 3.6.1 - 2023-06-14 =
+* Document new optional `$priority` arg for various API functions.
+* Document the new `--exclude-groups` WP CLI option.
+* Document the new `action_scheduler_init` hook.
+* Ensure actions within each claim are executed in the expected order.
+* Fix incorrect text domain.
+* Remove SHOW TABLES usage when checking if tables exist.
+
+= 3.6.0 - 2023-05-10 =
+* Add $unique parameter to function signatures.
+* Add a cast-to-int for extra safety before forming new DateTime object.
+* Add a hook allowing exceptions for consistently failing recurring actions.
+* Add action priorities.
+* Add init hook.
+* Always raise the time limit.
+* Bump minimatch from 3.0.4 to 3.0.8.
+* Bump yaml from 2.2.1 to 2.2.2.
+* Defensive coding relating to gaps in declared schedule types.
+* Do not process an action if it cannot be set to `in-progress`.
+* Filter view labels (status names) should be translatable | #919.
+* Fix WPCLI progress messages.
+* Improve data-store initialization flow.
+* Improve error handling across all supported PHP versions.
+* Improve logic for flushing the runtime cache.
+* Support exclusion of multiple groups.
+* Update lint-staged and Node/NPM requirements.
+* add CLI clean command.
+* add CLI exclude-group filter.
+* exclude past-due from list table all filter count.
+* throwing an exception if as_schedule_recurring_action interval param is not of type integer.
+
+= 3.5.4 - 2023-01-17 =
+* Add pre filters during action registration.
+* Async scheduling.
+* Calculate timeouts based on total actions.
+* Correctly order the parameters for `ActionScheduler_ActionFactory`'s calls to `single_unique`.
+* Fetch action in memory first before releasing claim to avoid deadlock.
+* PHP 8.2: declare property to fix creation of dynamic property warning.
+* PHP 8.2: fix "Using ${var} in strings is deprecated, use {$var} instead".
+* Prevent `undefined variable` warning for `$num_pastdue_actions`.
+
+= 3.5.3 - 2022-11-09 =
+* Query actions with partial match.
+
+= 3.5.2 - 2022-09-16 =
+* Fix - erroneous 3.5.1 release.
+
+= 3.5.1 - 2022-09-13 =
+* Maintenance on A/S docs.
+* fix: PHP 8.2 deprecated notice.
+
+= 3.5.0 - 2022-08-25 =
+* Add - The active view link within the "Tools > Scheduled Actions" screen is now clickable.
+* Add - A warning when there are past-due actions.
+* Enhancement - Added the ability to schedule unique actions via an atomic operation.
+* Enhancement - Improvements to cache invalidation when processing batches (when running on WordPress 6.0+).
+* Enhancement - If a recurring action is found to be consistently failing, it will stop being rescheduled.
+* Enhancement - Adds a new "Past Due" view to the scheduled actions list table.
+
+= 3.4.2 - 2022-06-08 =
+* Fix - Change the include for better linting.
+* Fix - update: Added Action scheduler completed action hook.
+
+= 3.4.1 - 2022-05-24 =
+* Fix - Change the include for better linting.
+* Fix - Fix the documented return type.
+
+= 3.4.0 - 2021-10-29 =
+* Enhancement - Number of items per page can now be set for the Scheduled Actions view (props @ovidiul). #771
+* Fix - Do not lower the max_execution_time if it is already set to 0 (unlimited) (props @barryhughes). #755
+* Fix - Avoid triggering autoloaders during the version resolution process (props @olegabr). #731 & #776
+* Dev - ActionScheduler_wcSystemStatus PHPCS fixes (props @ovidiul). #761
+* Dev - ActionScheduler_DBLogger.php PHPCS fixes (props @ovidiul). #768
+* Dev - Fixed phpcs for ActionScheduler_Schedule_Deprecated (props @ovidiul). #762
+* Dev - Improve actions table indices (props @glagonikas). #774 & #777
+* Dev - PHPCS fixes for ActionScheduler_DBStore.php (props @ovidiul). #769 & #778
+* Dev - PHPCS Fixes for ActionScheduler_Abstract_ListTable (props @ovidiul). #763 & #779
+* Dev - Adds new filter action_scheduler_claim_actions_order_by to allow tuning of the claim query (props @glagonikas). #773
+* Dev - PHPCS fixes for ActionScheduler_WpPostStore class (props @ovidiul). #780
+
+= 3.3.0 - 2021-09-15 =
+* Enhancement - Adds as_has_scheduled_action() to provide a performant way to test for existing actions. #645
+* Fix - Improves compatibility with environments where NO_ZERO_DATE is enabled. #519
+* Fix - Adds safety checks to guard against errors when our database tables cannot be created. #645
+* Dev - Now supports queries that use multiple statuses. #649
+* Dev - Minimum requirements for WordPress and PHP bumped (to 5.2 and 5.6 respectively). #723
+
+= 3.2.1 - 2021-06-21 =
+* Fix - Add extra safety/account for different versions of AS and different loading patterns. #714
+* Fix - Handle hidden columns (Tools ā Scheduled Actions) | #600.
+
+= 3.2.0 - 2021-06-03 =
+* Fix - Add "no ordering" option to as_next_scheduled_action().
+* Fix - Add secondary scheduled date checks when claiming actions (DBStore) | #634.
+* Fix - Add secondary scheduled date checks when claiming actions (wpPostStore) | #634.
+* Fix - Adds a new index to the action table, reducing the potential for deadlocks (props: @glagonikas).
+* Fix - Fix unit tests infrastructure and adapt tests to PHP 8.
+* Fix - Identify in-use data store.
+* Fix - Improve test_migration_is_scheduled.
+* Fix - PHP notice on list table.
+* Fix - Speed up clean up and batch selects.
+* Fix - Update pending dependencies.
+* Fix - [PHP 8.0] Only pass action arg values through to do_action_ref_array().
+* Fix - [PHP 8] Set the PHP version to 7.1 in composer.json for PHP 8 compatibility.
+* Fix - add is_initialized() to docs.
+* Fix - fix file permissions.
+* Fix - fixes #664 by replacing __ with esc_html__.
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail.php
new file mode 100755
index 00000000..f72108c3
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail.php
@@ -0,0 +1,115 @@
+
+ * The Gmail API lets you view and manage Gmail mailbox data like threads,
+ * messages, and labels.
+ *
+ *
+ * For more information about this service, see the API
+ * Documentation
+ *
+ *
+ * @author Google, Inc.
+ */
+class Gmail extends \WPMailSMTP\Vendor\Google\Service
+{
+ /** Read, compose, send, and permanently delete all your email from Gmail. */
+ const MAIL_GOOGLE_COM = "https://mail.google.com/";
+ /** Manage drafts and send emails when you interact with the add-on. */
+ const GMAIL_ADDONS_CURRENT_ACTION_COMPOSE = "https://www.googleapis.com/auth/gmail.addons.current.action.compose";
+ /** View your email messages when you interact with the add-on. */
+ const GMAIL_ADDONS_CURRENT_MESSAGE_ACTION = "https://www.googleapis.com/auth/gmail.addons.current.message.action";
+ /** View your email message metadata when the add-on is running. */
+ const GMAIL_ADDONS_CURRENT_MESSAGE_METADATA = "https://www.googleapis.com/auth/gmail.addons.current.message.metadata";
+ /** View your email messages when the add-on is running. */
+ const GMAIL_ADDONS_CURRENT_MESSAGE_READONLY = "https://www.googleapis.com/auth/gmail.addons.current.message.readonly";
+ /** Manage drafts and send emails. */
+ const GMAIL_COMPOSE = "https://www.googleapis.com/auth/gmail.compose";
+ /** Add emails into your Gmail mailbox. */
+ const GMAIL_INSERT = "https://www.googleapis.com/auth/gmail.insert";
+ /** See and edit your email labels. */
+ const GMAIL_LABELS = "https://www.googleapis.com/auth/gmail.labels";
+ /** View your email message metadata such as labels and headers, but not the email body. */
+ const GMAIL_METADATA = "https://www.googleapis.com/auth/gmail.metadata";
+ /** Read, compose, and send emails from your Gmail account. */
+ const GMAIL_MODIFY = "https://www.googleapis.com/auth/gmail.modify";
+ /** View your email messages and settings. */
+ const GMAIL_READONLY = "https://www.googleapis.com/auth/gmail.readonly";
+ /** Send email on your behalf. */
+ const GMAIL_SEND = "https://www.googleapis.com/auth/gmail.send";
+ /** See, edit, create, or change your email settings and filters in Gmail. */
+ const GMAIL_SETTINGS_BASIC = "https://www.googleapis.com/auth/gmail.settings.basic";
+ /** Manage your sensitive mail settings, including who can manage your mail. */
+ const GMAIL_SETTINGS_SHARING = "https://www.googleapis.com/auth/gmail.settings.sharing";
+ public $users;
+ public $users_drafts;
+ public $users_history;
+ public $users_labels;
+ public $users_messages;
+ public $users_messages_attachments;
+ public $users_settings;
+ public $users_settings_cse_identities;
+ public $users_settings_cse_keypairs;
+ public $users_settings_delegates;
+ public $users_settings_filters;
+ public $users_settings_forwardingAddresses;
+ public $users_settings_sendAs;
+ public $users_settings_sendAs_smimeInfo;
+ public $users_threads;
+ public $rootUrlTemplate;
+ /**
+ * Constructs the internal representation of the Gmail service.
+ *
+ * @param Client|array $clientOrConfig The client used to deliver requests, or a
+ * config array to pass to a new Client instance.
+ * @param string $rootUrl The root URL used for requests to the service.
+ */
+ public function __construct($clientOrConfig = [], $rootUrl = null)
+ {
+ parent::__construct($clientOrConfig);
+ $this->rootUrl = $rootUrl ?: 'https://gmail.googleapis.com/';
+ $this->rootUrlTemplate = $rootUrl ?: 'https://gmail.UNIVERSE_DOMAIN/';
+ $this->servicePath = '';
+ $this->batchPath = 'batch';
+ $this->version = 'v1';
+ $this->serviceName = 'gmail';
+ $this->users = new Gmail\Resource\Users($this, $this->serviceName, 'users', ['methods' => ['getProfile' => ['path' => 'gmail/v1/users/{userId}/profile', 'httpMethod' => 'GET', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'temporaryEeccBypass' => ['location' => 'query', 'type' => 'boolean']]], 'stop' => ['path' => 'gmail/v1/users/{userId}/stop', 'httpMethod' => 'POST', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'watch' => ['path' => 'gmail/v1/users/{userId}/watch', 'httpMethod' => 'POST', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true]]]]]);
+ $this->users_drafts = new Gmail\Resource\UsersDrafts($this, $this->serviceName, 'drafts', ['methods' => ['create' => ['path' => 'gmail/v1/users/{userId}/drafts', 'httpMethod' => 'POST', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'delete' => ['path' => 'gmail/v1/users/{userId}/drafts/{id}', 'httpMethod' => 'DELETE', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'id' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'get' => ['path' => 'gmail/v1/users/{userId}/drafts/{id}', 'httpMethod' => 'GET', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'id' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'format' => ['location' => 'query', 'type' => 'string']]], 'list' => ['path' => 'gmail/v1/users/{userId}/drafts', 'httpMethod' => 'GET', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'includeSpamTrash' => ['location' => 'query', 'type' => 'boolean'], 'maxResults' => ['location' => 'query', 'type' => 'integer'], 'pageToken' => ['location' => 'query', 'type' => 'string'], 'q' => ['location' => 'query', 'type' => 'string']]], 'send' => ['path' => 'gmail/v1/users/{userId}/drafts/send', 'httpMethod' => 'POST', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'update' => ['path' => 'gmail/v1/users/{userId}/drafts/{id}', 'httpMethod' => 'PUT', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'id' => ['location' => 'path', 'type' => 'string', 'required' => \true]]]]]);
+ $this->users_history = new Gmail\Resource\UsersHistory($this, $this->serviceName, 'history', ['methods' => ['list' => ['path' => 'gmail/v1/users/{userId}/history', 'httpMethod' => 'GET', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'historyTypes' => ['location' => 'query', 'type' => 'string', 'repeated' => \true], 'labelId' => ['location' => 'query', 'type' => 'string'], 'maxResults' => ['location' => 'query', 'type' => 'integer'], 'pageToken' => ['location' => 'query', 'type' => 'string'], 'startHistoryId' => ['location' => 'query', 'type' => 'string']]]]]);
+ $this->users_labels = new Gmail\Resource\UsersLabels($this, $this->serviceName, 'labels', ['methods' => ['create' => ['path' => 'gmail/v1/users/{userId}/labels', 'httpMethod' => 'POST', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'delete' => ['path' => 'gmail/v1/users/{userId}/labels/{id}', 'httpMethod' => 'DELETE', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'id' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'get' => ['path' => 'gmail/v1/users/{userId}/labels/{id}', 'httpMethod' => 'GET', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'id' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'list' => ['path' => 'gmail/v1/users/{userId}/labels', 'httpMethod' => 'GET', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'patch' => ['path' => 'gmail/v1/users/{userId}/labels/{id}', 'httpMethod' => 'PATCH', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'id' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'update' => ['path' => 'gmail/v1/users/{userId}/labels/{id}', 'httpMethod' => 'PUT', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'id' => ['location' => 'path', 'type' => 'string', 'required' => \true]]]]]);
+ $this->users_messages = new Gmail\Resource\UsersMessages($this, $this->serviceName, 'messages', ['methods' => ['batchDelete' => ['path' => 'gmail/v1/users/{userId}/messages/batchDelete', 'httpMethod' => 'POST', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'batchModify' => ['path' => 'gmail/v1/users/{userId}/messages/batchModify', 'httpMethod' => 'POST', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'delete' => ['path' => 'gmail/v1/users/{userId}/messages/{id}', 'httpMethod' => 'DELETE', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'id' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'get' => ['path' => 'gmail/v1/users/{userId}/messages/{id}', 'httpMethod' => 'GET', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'id' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'format' => ['location' => 'query', 'type' => 'string'], 'metadataHeaders' => ['location' => 'query', 'type' => 'string', 'repeated' => \true], 'temporaryEeccBypass' => ['location' => 'query', 'type' => 'boolean']]], 'import' => ['path' => 'gmail/v1/users/{userId}/messages/import', 'httpMethod' => 'POST', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'deleted' => ['location' => 'query', 'type' => 'boolean'], 'internalDateSource' => ['location' => 'query', 'type' => 'string'], 'neverMarkSpam' => ['location' => 'query', 'type' => 'boolean'], 'processForCalendar' => ['location' => 'query', 'type' => 'boolean']]], 'insert' => ['path' => 'gmail/v1/users/{userId}/messages', 'httpMethod' => 'POST', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'deleted' => ['location' => 'query', 'type' => 'boolean'], 'internalDateSource' => ['location' => 'query', 'type' => 'string']]], 'list' => ['path' => 'gmail/v1/users/{userId}/messages', 'httpMethod' => 'GET', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'includeSpamTrash' => ['location' => 'query', 'type' => 'boolean'], 'labelIds' => ['location' => 'query', 'type' => 'string', 'repeated' => \true], 'maxResults' => ['location' => 'query', 'type' => 'integer'], 'pageToken' => ['location' => 'query', 'type' => 'string'], 'q' => ['location' => 'query', 'type' => 'string'], 'temporaryEeccBypass' => ['location' => 'query', 'type' => 'boolean']]], 'modify' => ['path' => 'gmail/v1/users/{userId}/messages/{id}/modify', 'httpMethod' => 'POST', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'id' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'send' => ['path' => 'gmail/v1/users/{userId}/messages/send', 'httpMethod' => 'POST', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'trash' => ['path' => 'gmail/v1/users/{userId}/messages/{id}/trash', 'httpMethod' => 'POST', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'id' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'untrash' => ['path' => 'gmail/v1/users/{userId}/messages/{id}/untrash', 'httpMethod' => 'POST', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'id' => ['location' => 'path', 'type' => 'string', 'required' => \true]]]]]);
+ $this->users_messages_attachments = new Gmail\Resource\UsersMessagesAttachments($this, $this->serviceName, 'attachments', ['methods' => ['get' => ['path' => 'gmail/v1/users/{userId}/messages/{messageId}/attachments/{id}', 'httpMethod' => 'GET', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'messageId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'id' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'temporaryEeccBypass' => ['location' => 'query', 'type' => 'boolean']]]]]);
+ $this->users_settings = new Gmail\Resource\UsersSettings($this, $this->serviceName, 'settings', ['methods' => ['getAutoForwarding' => ['path' => 'gmail/v1/users/{userId}/settings/autoForwarding', 'httpMethod' => 'GET', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'getImap' => ['path' => 'gmail/v1/users/{userId}/settings/imap', 'httpMethod' => 'GET', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'getLanguage' => ['path' => 'gmail/v1/users/{userId}/settings/language', 'httpMethod' => 'GET', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'getPop' => ['path' => 'gmail/v1/users/{userId}/settings/pop', 'httpMethod' => 'GET', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'getVacation' => ['path' => 'gmail/v1/users/{userId}/settings/vacation', 'httpMethod' => 'GET', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'updateAutoForwarding' => ['path' => 'gmail/v1/users/{userId}/settings/autoForwarding', 'httpMethod' => 'PUT', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'updateImap' => ['path' => 'gmail/v1/users/{userId}/settings/imap', 'httpMethod' => 'PUT', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'updateLanguage' => ['path' => 'gmail/v1/users/{userId}/settings/language', 'httpMethod' => 'PUT', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'updatePop' => ['path' => 'gmail/v1/users/{userId}/settings/pop', 'httpMethod' => 'PUT', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'updateVacation' => ['path' => 'gmail/v1/users/{userId}/settings/vacation', 'httpMethod' => 'PUT', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true]]]]]);
+ $this->users_settings_cse_identities = new Gmail\Resource\UsersSettingsCseIdentities($this, $this->serviceName, 'identities', ['methods' => ['create' => ['path' => 'gmail/v1/users/{userId}/settings/cse/identities', 'httpMethod' => 'POST', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'delete' => ['path' => 'gmail/v1/users/{userId}/settings/cse/identities/{cseEmailAddress}', 'httpMethod' => 'DELETE', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'cseEmailAddress' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'get' => ['path' => 'gmail/v1/users/{userId}/settings/cse/identities/{cseEmailAddress}', 'httpMethod' => 'GET', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'cseEmailAddress' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'list' => ['path' => 'gmail/v1/users/{userId}/settings/cse/identities', 'httpMethod' => 'GET', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'pageSize' => ['location' => 'query', 'type' => 'integer'], 'pageToken' => ['location' => 'query', 'type' => 'string']]], 'patch' => ['path' => 'gmail/v1/users/{userId}/settings/cse/identities/{emailAddress}', 'httpMethod' => 'PATCH', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'emailAddress' => ['location' => 'path', 'type' => 'string', 'required' => \true]]]]]);
+ $this->users_settings_cse_keypairs = new Gmail\Resource\UsersSettingsCseKeypairs($this, $this->serviceName, 'keypairs', ['methods' => ['create' => ['path' => 'gmail/v1/users/{userId}/settings/cse/keypairs', 'httpMethod' => 'POST', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'disable' => ['path' => 'gmail/v1/users/{userId}/settings/cse/keypairs/{keyPairId}:disable', 'httpMethod' => 'POST', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'keyPairId' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'enable' => ['path' => 'gmail/v1/users/{userId}/settings/cse/keypairs/{keyPairId}:enable', 'httpMethod' => 'POST', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'keyPairId' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'get' => ['path' => 'gmail/v1/users/{userId}/settings/cse/keypairs/{keyPairId}', 'httpMethod' => 'GET', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'keyPairId' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'list' => ['path' => 'gmail/v1/users/{userId}/settings/cse/keypairs', 'httpMethod' => 'GET', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'pageSize' => ['location' => 'query', 'type' => 'integer'], 'pageToken' => ['location' => 'query', 'type' => 'string']]], 'obliterate' => ['path' => 'gmail/v1/users/{userId}/settings/cse/keypairs/{keyPairId}:obliterate', 'httpMethod' => 'POST', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'keyPairId' => ['location' => 'path', 'type' => 'string', 'required' => \true]]]]]);
+ $this->users_settings_delegates = new Gmail\Resource\UsersSettingsDelegates($this, $this->serviceName, 'delegates', ['methods' => ['create' => ['path' => 'gmail/v1/users/{userId}/settings/delegates', 'httpMethod' => 'POST', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'delete' => ['path' => 'gmail/v1/users/{userId}/settings/delegates/{delegateEmail}', 'httpMethod' => 'DELETE', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'delegateEmail' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'get' => ['path' => 'gmail/v1/users/{userId}/settings/delegates/{delegateEmail}', 'httpMethod' => 'GET', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'delegateEmail' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'list' => ['path' => 'gmail/v1/users/{userId}/settings/delegates', 'httpMethod' => 'GET', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true]]]]]);
+ $this->users_settings_filters = new Gmail\Resource\UsersSettingsFilters($this, $this->serviceName, 'filters', ['methods' => ['create' => ['path' => 'gmail/v1/users/{userId}/settings/filters', 'httpMethod' => 'POST', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'delete' => ['path' => 'gmail/v1/users/{userId}/settings/filters/{id}', 'httpMethod' => 'DELETE', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'id' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'get' => ['path' => 'gmail/v1/users/{userId}/settings/filters/{id}', 'httpMethod' => 'GET', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'id' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'list' => ['path' => 'gmail/v1/users/{userId}/settings/filters', 'httpMethod' => 'GET', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true]]]]]);
+ $this->users_settings_forwardingAddresses = new Gmail\Resource\UsersSettingsForwardingAddresses($this, $this->serviceName, 'forwardingAddresses', ['methods' => ['create' => ['path' => 'gmail/v1/users/{userId}/settings/forwardingAddresses', 'httpMethod' => 'POST', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'delete' => ['path' => 'gmail/v1/users/{userId}/settings/forwardingAddresses/{forwardingEmail}', 'httpMethod' => 'DELETE', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'forwardingEmail' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'get' => ['path' => 'gmail/v1/users/{userId}/settings/forwardingAddresses/{forwardingEmail}', 'httpMethod' => 'GET', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'forwardingEmail' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'list' => ['path' => 'gmail/v1/users/{userId}/settings/forwardingAddresses', 'httpMethod' => 'GET', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true]]]]]);
+ $this->users_settings_sendAs = new Gmail\Resource\UsersSettingsSendAs($this, $this->serviceName, 'sendAs', ['methods' => ['create' => ['path' => 'gmail/v1/users/{userId}/settings/sendAs', 'httpMethod' => 'POST', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'delete' => ['path' => 'gmail/v1/users/{userId}/settings/sendAs/{sendAsEmail}', 'httpMethod' => 'DELETE', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'sendAsEmail' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'get' => ['path' => 'gmail/v1/users/{userId}/settings/sendAs/{sendAsEmail}', 'httpMethod' => 'GET', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'sendAsEmail' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'list' => ['path' => 'gmail/v1/users/{userId}/settings/sendAs', 'httpMethod' => 'GET', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'patch' => ['path' => 'gmail/v1/users/{userId}/settings/sendAs/{sendAsEmail}', 'httpMethod' => 'PATCH', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'sendAsEmail' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'update' => ['path' => 'gmail/v1/users/{userId}/settings/sendAs/{sendAsEmail}', 'httpMethod' => 'PUT', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'sendAsEmail' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'verify' => ['path' => 'gmail/v1/users/{userId}/settings/sendAs/{sendAsEmail}/verify', 'httpMethod' => 'POST', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'sendAsEmail' => ['location' => 'path', 'type' => 'string', 'required' => \true]]]]]);
+ $this->users_settings_sendAs_smimeInfo = new Gmail\Resource\UsersSettingsSendAsSmimeInfo($this, $this->serviceName, 'smimeInfo', ['methods' => ['delete' => ['path' => 'gmail/v1/users/{userId}/settings/sendAs/{sendAsEmail}/smimeInfo/{id}', 'httpMethod' => 'DELETE', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'sendAsEmail' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'id' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'get' => ['path' => 'gmail/v1/users/{userId}/settings/sendAs/{sendAsEmail}/smimeInfo/{id}', 'httpMethod' => 'GET', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'sendAsEmail' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'id' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'insert' => ['path' => 'gmail/v1/users/{userId}/settings/sendAs/{sendAsEmail}/smimeInfo', 'httpMethod' => 'POST', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'sendAsEmail' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'list' => ['path' => 'gmail/v1/users/{userId}/settings/sendAs/{sendAsEmail}/smimeInfo', 'httpMethod' => 'GET', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'sendAsEmail' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'setDefault' => ['path' => 'gmail/v1/users/{userId}/settings/sendAs/{sendAsEmail}/smimeInfo/{id}/setDefault', 'httpMethod' => 'POST', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'sendAsEmail' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'id' => ['location' => 'path', 'type' => 'string', 'required' => \true]]]]]);
+ $this->users_threads = new Gmail\Resource\UsersThreads($this, $this->serviceName, 'threads', ['methods' => ['delete' => ['path' => 'gmail/v1/users/{userId}/threads/{id}', 'httpMethod' => 'DELETE', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'id' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'get' => ['path' => 'gmail/v1/users/{userId}/threads/{id}', 'httpMethod' => 'GET', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'id' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'format' => ['location' => 'query', 'type' => 'string'], 'metadataHeaders' => ['location' => 'query', 'type' => 'string', 'repeated' => \true], 'temporaryEeccBypass' => ['location' => 'query', 'type' => 'boolean']]], 'list' => ['path' => 'gmail/v1/users/{userId}/threads', 'httpMethod' => 'GET', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'includeSpamTrash' => ['location' => 'query', 'type' => 'boolean'], 'labelIds' => ['location' => 'query', 'type' => 'string', 'repeated' => \true], 'maxResults' => ['location' => 'query', 'type' => 'integer'], 'pageToken' => ['location' => 'query', 'type' => 'string'], 'q' => ['location' => 'query', 'type' => 'string'], 'temporaryEeccBypass' => ['location' => 'query', 'type' => 'boolean']]], 'modify' => ['path' => 'gmail/v1/users/{userId}/threads/{id}/modify', 'httpMethod' => 'POST', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'id' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'trash' => ['path' => 'gmail/v1/users/{userId}/threads/{id}/trash', 'httpMethod' => 'POST', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'id' => ['location' => 'path', 'type' => 'string', 'required' => \true]]], 'untrash' => ['path' => 'gmail/v1/users/{userId}/threads/{id}/untrash', 'httpMethod' => 'POST', 'parameters' => ['userId' => ['location' => 'path', 'type' => 'string', 'required' => \true], 'id' => ['location' => 'path', 'type' => 'string', 'required' => \true]]]]]);
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(Gmail::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/AutoForwarding.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/AutoForwarding.php
new file mode 100755
index 00000000..0a8284a7
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/AutoForwarding.php
@@ -0,0 +1,78 @@
+disposition = $disposition;
+ }
+ /**
+ * @return string
+ */
+ public function getDisposition()
+ {
+ return $this->disposition;
+ }
+ /**
+ * @param string
+ */
+ public function setEmailAddress($emailAddress)
+ {
+ $this->emailAddress = $emailAddress;
+ }
+ /**
+ * @return string
+ */
+ public function getEmailAddress()
+ {
+ return $this->emailAddress;
+ }
+ /**
+ * @param bool
+ */
+ public function setEnabled($enabled)
+ {
+ $this->enabled = $enabled;
+ }
+ /**
+ * @return bool
+ */
+ public function getEnabled()
+ {
+ return $this->enabled;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(AutoForwarding::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_AutoForwarding');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/BatchDeleteMessagesRequest.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/BatchDeleteMessagesRequest.php
new file mode 100755
index 00000000..73496099
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/BatchDeleteMessagesRequest.php
@@ -0,0 +1,43 @@
+ids = $ids;
+ }
+ /**
+ * @return string[]
+ */
+ public function getIds()
+ {
+ return $this->ids;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(BatchDeleteMessagesRequest::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_BatchDeleteMessagesRequest');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/BatchModifyMessagesRequest.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/BatchModifyMessagesRequest.php
new file mode 100755
index 00000000..25ab10b1
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/BatchModifyMessagesRequest.php
@@ -0,0 +1,79 @@
+addLabelIds = $addLabelIds;
+ }
+ /**
+ * @return string[]
+ */
+ public function getAddLabelIds()
+ {
+ return $this->addLabelIds;
+ }
+ /**
+ * @param string[]
+ */
+ public function setIds($ids)
+ {
+ $this->ids = $ids;
+ }
+ /**
+ * @return string[]
+ */
+ public function getIds()
+ {
+ return $this->ids;
+ }
+ /**
+ * @param string[]
+ */
+ public function setRemoveLabelIds($removeLabelIds)
+ {
+ $this->removeLabelIds = $removeLabelIds;
+ }
+ /**
+ * @return string[]
+ */
+ public function getRemoveLabelIds()
+ {
+ return $this->removeLabelIds;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(BatchModifyMessagesRequest::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_BatchModifyMessagesRequest');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/CseIdentity.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/CseIdentity.php
new file mode 100755
index 00000000..959fbd3f
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/CseIdentity.php
@@ -0,0 +1,76 @@
+emailAddress = $emailAddress;
+ }
+ /**
+ * @return string
+ */
+ public function getEmailAddress()
+ {
+ return $this->emailAddress;
+ }
+ /**
+ * @param string
+ */
+ public function setPrimaryKeyPairId($primaryKeyPairId)
+ {
+ $this->primaryKeyPairId = $primaryKeyPairId;
+ }
+ /**
+ * @return string
+ */
+ public function getPrimaryKeyPairId()
+ {
+ return $this->primaryKeyPairId;
+ }
+ /**
+ * @param SignAndEncryptKeyPairs
+ */
+ public function setSignAndEncryptKeyPairs(SignAndEncryptKeyPairs $signAndEncryptKeyPairs)
+ {
+ $this->signAndEncryptKeyPairs = $signAndEncryptKeyPairs;
+ }
+ /**
+ * @return SignAndEncryptKeyPairs
+ */
+ public function getSignAndEncryptKeyPairs()
+ {
+ return $this->signAndEncryptKeyPairs;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(CseIdentity::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_CseIdentity');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/CseKeyPair.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/CseKeyPair.php
new file mode 100755
index 00000000..97f53655
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/CseKeyPair.php
@@ -0,0 +1,149 @@
+disableTime = $disableTime;
+ }
+ /**
+ * @return string
+ */
+ public function getDisableTime()
+ {
+ return $this->disableTime;
+ }
+ /**
+ * @param string
+ */
+ public function setEnablementState($enablementState)
+ {
+ $this->enablementState = $enablementState;
+ }
+ /**
+ * @return string
+ */
+ public function getEnablementState()
+ {
+ return $this->enablementState;
+ }
+ /**
+ * @param string
+ */
+ public function setKeyPairId($keyPairId)
+ {
+ $this->keyPairId = $keyPairId;
+ }
+ /**
+ * @return string
+ */
+ public function getKeyPairId()
+ {
+ return $this->keyPairId;
+ }
+ /**
+ * @param string
+ */
+ public function setPem($pem)
+ {
+ $this->pem = $pem;
+ }
+ /**
+ * @return string
+ */
+ public function getPem()
+ {
+ return $this->pem;
+ }
+ /**
+ * @param string
+ */
+ public function setPkcs7($pkcs7)
+ {
+ $this->pkcs7 = $pkcs7;
+ }
+ /**
+ * @return string
+ */
+ public function getPkcs7()
+ {
+ return $this->pkcs7;
+ }
+ /**
+ * @param CsePrivateKeyMetadata[]
+ */
+ public function setPrivateKeyMetadata($privateKeyMetadata)
+ {
+ $this->privateKeyMetadata = $privateKeyMetadata;
+ }
+ /**
+ * @return CsePrivateKeyMetadata[]
+ */
+ public function getPrivateKeyMetadata()
+ {
+ return $this->privateKeyMetadata;
+ }
+ /**
+ * @param string[]
+ */
+ public function setSubjectEmailAddresses($subjectEmailAddresses)
+ {
+ $this->subjectEmailAddresses = $subjectEmailAddresses;
+ }
+ /**
+ * @return string[]
+ */
+ public function getSubjectEmailAddresses()
+ {
+ return $this->subjectEmailAddresses;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(CseKeyPair::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_CseKeyPair');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/CsePrivateKeyMetadata.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/CsePrivateKeyMetadata.php
new file mode 100755
index 00000000..84a965ca
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/CsePrivateKeyMetadata.php
@@ -0,0 +1,74 @@
+hardwareKeyMetadata = $hardwareKeyMetadata;
+ }
+ /**
+ * @return HardwareKeyMetadata
+ */
+ public function getHardwareKeyMetadata()
+ {
+ return $this->hardwareKeyMetadata;
+ }
+ /**
+ * @param KaclsKeyMetadata
+ */
+ public function setKaclsKeyMetadata(KaclsKeyMetadata $kaclsKeyMetadata)
+ {
+ $this->kaclsKeyMetadata = $kaclsKeyMetadata;
+ }
+ /**
+ * @return KaclsKeyMetadata
+ */
+ public function getKaclsKeyMetadata()
+ {
+ return $this->kaclsKeyMetadata;
+ }
+ /**
+ * @param string
+ */
+ public function setPrivateKeyMetadataId($privateKeyMetadataId)
+ {
+ $this->privateKeyMetadataId = $privateKeyMetadataId;
+ }
+ /**
+ * @return string
+ */
+ public function getPrivateKeyMetadataId()
+ {
+ return $this->privateKeyMetadataId;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(CsePrivateKeyMetadata::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_CsePrivateKeyMetadata');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Delegate.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Delegate.php
new file mode 100755
index 00000000..f369e61f
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Delegate.php
@@ -0,0 +1,60 @@
+delegateEmail = $delegateEmail;
+ }
+ /**
+ * @return string
+ */
+ public function getDelegateEmail()
+ {
+ return $this->delegateEmail;
+ }
+ /**
+ * @param string
+ */
+ public function setVerificationStatus($verificationStatus)
+ {
+ $this->verificationStatus = $verificationStatus;
+ }
+ /**
+ * @return string
+ */
+ public function getVerificationStatus()
+ {
+ return $this->verificationStatus;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(Delegate::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_Delegate');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/DisableCseKeyPairRequest.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/DisableCseKeyPairRequest.php
new file mode 100755
index 00000000..ca144734
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/DisableCseKeyPairRequest.php
@@ -0,0 +1,24 @@
+id = $id;
+ }
+ /**
+ * @return string
+ */
+ public function getId()
+ {
+ return $this->id;
+ }
+ /**
+ * @param Message
+ */
+ public function setMessage(Message $message)
+ {
+ $this->message = $message;
+ }
+ /**
+ * @return Message
+ */
+ public function getMessage()
+ {
+ return $this->message;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(Draft::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_Draft');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/EnableCseKeyPairRequest.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/EnableCseKeyPairRequest.php
new file mode 100755
index 00000000..3bb99c45
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/EnableCseKeyPairRequest.php
@@ -0,0 +1,24 @@
+action = $action;
+ }
+ /**
+ * @return FilterAction
+ */
+ public function getAction()
+ {
+ return $this->action;
+ }
+ /**
+ * @param FilterCriteria
+ */
+ public function setCriteria(FilterCriteria $criteria)
+ {
+ $this->criteria = $criteria;
+ }
+ /**
+ * @return FilterCriteria
+ */
+ public function getCriteria()
+ {
+ return $this->criteria;
+ }
+ /**
+ * @param string
+ */
+ public function setId($id)
+ {
+ $this->id = $id;
+ }
+ /**
+ * @return string
+ */
+ public function getId()
+ {
+ return $this->id;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(Filter::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_Filter');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/FilterAction.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/FilterAction.php
new file mode 100755
index 00000000..3020373b
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/FilterAction.php
@@ -0,0 +1,79 @@
+addLabelIds = $addLabelIds;
+ }
+ /**
+ * @return string[]
+ */
+ public function getAddLabelIds()
+ {
+ return $this->addLabelIds;
+ }
+ /**
+ * @param string
+ */
+ public function setForward($forward)
+ {
+ $this->forward = $forward;
+ }
+ /**
+ * @return string
+ */
+ public function getForward()
+ {
+ return $this->forward;
+ }
+ /**
+ * @param string[]
+ */
+ public function setRemoveLabelIds($removeLabelIds)
+ {
+ $this->removeLabelIds = $removeLabelIds;
+ }
+ /**
+ * @return string[]
+ */
+ public function getRemoveLabelIds()
+ {
+ return $this->removeLabelIds;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(FilterAction::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_FilterAction');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/FilterCriteria.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/FilterCriteria.php
new file mode 100755
index 00000000..50ca5b90
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/FilterCriteria.php
@@ -0,0 +1,186 @@
+excludeChats = $excludeChats;
+ }
+ /**
+ * @return bool
+ */
+ public function getExcludeChats()
+ {
+ return $this->excludeChats;
+ }
+ /**
+ * @param string
+ */
+ public function setFrom($from)
+ {
+ $this->from = $from;
+ }
+ /**
+ * @return string
+ */
+ public function getFrom()
+ {
+ return $this->from;
+ }
+ /**
+ * @param bool
+ */
+ public function setHasAttachment($hasAttachment)
+ {
+ $this->hasAttachment = $hasAttachment;
+ }
+ /**
+ * @return bool
+ */
+ public function getHasAttachment()
+ {
+ return $this->hasAttachment;
+ }
+ /**
+ * @param string
+ */
+ public function setNegatedQuery($negatedQuery)
+ {
+ $this->negatedQuery = $negatedQuery;
+ }
+ /**
+ * @return string
+ */
+ public function getNegatedQuery()
+ {
+ return $this->negatedQuery;
+ }
+ /**
+ * @param string
+ */
+ public function setQuery($query)
+ {
+ $this->query = $query;
+ }
+ /**
+ * @return string
+ */
+ public function getQuery()
+ {
+ return $this->query;
+ }
+ /**
+ * @param int
+ */
+ public function setSize($size)
+ {
+ $this->size = $size;
+ }
+ /**
+ * @return int
+ */
+ public function getSize()
+ {
+ return $this->size;
+ }
+ /**
+ * @param string
+ */
+ public function setSizeComparison($sizeComparison)
+ {
+ $this->sizeComparison = $sizeComparison;
+ }
+ /**
+ * @return string
+ */
+ public function getSizeComparison()
+ {
+ return $this->sizeComparison;
+ }
+ /**
+ * @param string
+ */
+ public function setSubject($subject)
+ {
+ $this->subject = $subject;
+ }
+ /**
+ * @return string
+ */
+ public function getSubject()
+ {
+ return $this->subject;
+ }
+ /**
+ * @param string
+ */
+ public function setTo($to)
+ {
+ $this->to = $to;
+ }
+ /**
+ * @return string
+ */
+ public function getTo()
+ {
+ return $this->to;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(FilterCriteria::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_FilterCriteria');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ForwardingAddress.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ForwardingAddress.php
new file mode 100755
index 00000000..94a85509
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ForwardingAddress.php
@@ -0,0 +1,60 @@
+forwardingEmail = $forwardingEmail;
+ }
+ /**
+ * @return string
+ */
+ public function getForwardingEmail()
+ {
+ return $this->forwardingEmail;
+ }
+ /**
+ * @param string
+ */
+ public function setVerificationStatus($verificationStatus)
+ {
+ $this->verificationStatus = $verificationStatus;
+ }
+ /**
+ * @return string
+ */
+ public function getVerificationStatus()
+ {
+ return $this->verificationStatus;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(ForwardingAddress::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_ForwardingAddress');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/HardwareKeyMetadata.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/HardwareKeyMetadata.php
new file mode 100755
index 00000000..a4de0d95
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/HardwareKeyMetadata.php
@@ -0,0 +1,42 @@
+description = $description;
+ }
+ /**
+ * @return string
+ */
+ public function getDescription()
+ {
+ return $this->description;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(HardwareKeyMetadata::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_HardwareKeyMetadata');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/History.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/History.php
new file mode 100755
index 00000000..80cb1125
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/History.php
@@ -0,0 +1,123 @@
+id = $id;
+ }
+ /**
+ * @return string
+ */
+ public function getId()
+ {
+ return $this->id;
+ }
+ /**
+ * @param HistoryLabelAdded[]
+ */
+ public function setLabelsAdded($labelsAdded)
+ {
+ $this->labelsAdded = $labelsAdded;
+ }
+ /**
+ * @return HistoryLabelAdded[]
+ */
+ public function getLabelsAdded()
+ {
+ return $this->labelsAdded;
+ }
+ /**
+ * @param HistoryLabelRemoved[]
+ */
+ public function setLabelsRemoved($labelsRemoved)
+ {
+ $this->labelsRemoved = $labelsRemoved;
+ }
+ /**
+ * @return HistoryLabelRemoved[]
+ */
+ public function getLabelsRemoved()
+ {
+ return $this->labelsRemoved;
+ }
+ /**
+ * @param Message[]
+ */
+ public function setMessages($messages)
+ {
+ $this->messages = $messages;
+ }
+ /**
+ * @return Message[]
+ */
+ public function getMessages()
+ {
+ return $this->messages;
+ }
+ /**
+ * @param HistoryMessageAdded[]
+ */
+ public function setMessagesAdded($messagesAdded)
+ {
+ $this->messagesAdded = $messagesAdded;
+ }
+ /**
+ * @return HistoryMessageAdded[]
+ */
+ public function getMessagesAdded()
+ {
+ return $this->messagesAdded;
+ }
+ /**
+ * @param HistoryMessageDeleted[]
+ */
+ public function setMessagesDeleted($messagesDeleted)
+ {
+ $this->messagesDeleted = $messagesDeleted;
+ }
+ /**
+ * @return HistoryMessageDeleted[]
+ */
+ public function getMessagesDeleted()
+ {
+ return $this->messagesDeleted;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(History::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_History');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/HistoryLabelAdded.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/HistoryLabelAdded.php
new file mode 100755
index 00000000..06ca3471
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/HistoryLabelAdded.php
@@ -0,0 +1,59 @@
+labelIds = $labelIds;
+ }
+ /**
+ * @return string[]
+ */
+ public function getLabelIds()
+ {
+ return $this->labelIds;
+ }
+ /**
+ * @param Message
+ */
+ public function setMessage(Message $message)
+ {
+ $this->message = $message;
+ }
+ /**
+ * @return Message
+ */
+ public function getMessage()
+ {
+ return $this->message;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(HistoryLabelAdded::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_HistoryLabelAdded');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/HistoryLabelRemoved.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/HistoryLabelRemoved.php
new file mode 100755
index 00000000..f2d01a09
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/HistoryLabelRemoved.php
@@ -0,0 +1,59 @@
+labelIds = $labelIds;
+ }
+ /**
+ * @return string[]
+ */
+ public function getLabelIds()
+ {
+ return $this->labelIds;
+ }
+ /**
+ * @param Message
+ */
+ public function setMessage(Message $message)
+ {
+ $this->message = $message;
+ }
+ /**
+ * @return Message
+ */
+ public function getMessage()
+ {
+ return $this->message;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(HistoryLabelRemoved::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_HistoryLabelRemoved');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/HistoryMessageAdded.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/HistoryMessageAdded.php
new file mode 100755
index 00000000..782d19ba
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/HistoryMessageAdded.php
@@ -0,0 +1,40 @@
+message = $message;
+ }
+ /**
+ * @return Message
+ */
+ public function getMessage()
+ {
+ return $this->message;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(HistoryMessageAdded::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_HistoryMessageAdded');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/HistoryMessageDeleted.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/HistoryMessageDeleted.php
new file mode 100755
index 00000000..e16aed0a
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/HistoryMessageDeleted.php
@@ -0,0 +1,40 @@
+message = $message;
+ }
+ /**
+ * @return Message
+ */
+ public function getMessage()
+ {
+ return $this->message;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(HistoryMessageDeleted::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_HistoryMessageDeleted');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ImapSettings.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ImapSettings.php
new file mode 100755
index 00000000..1bd7983f
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ImapSettings.php
@@ -0,0 +1,96 @@
+autoExpunge = $autoExpunge;
+ }
+ /**
+ * @return bool
+ */
+ public function getAutoExpunge()
+ {
+ return $this->autoExpunge;
+ }
+ /**
+ * @param bool
+ */
+ public function setEnabled($enabled)
+ {
+ $this->enabled = $enabled;
+ }
+ /**
+ * @return bool
+ */
+ public function getEnabled()
+ {
+ return $this->enabled;
+ }
+ /**
+ * @param string
+ */
+ public function setExpungeBehavior($expungeBehavior)
+ {
+ $this->expungeBehavior = $expungeBehavior;
+ }
+ /**
+ * @return string
+ */
+ public function getExpungeBehavior()
+ {
+ return $this->expungeBehavior;
+ }
+ /**
+ * @param int
+ */
+ public function setMaxFolderSize($maxFolderSize)
+ {
+ $this->maxFolderSize = $maxFolderSize;
+ }
+ /**
+ * @return int
+ */
+ public function getMaxFolderSize()
+ {
+ return $this->maxFolderSize;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(ImapSettings::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_ImapSettings');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/KaclsKeyMetadata.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/KaclsKeyMetadata.php
new file mode 100755
index 00000000..86afa1b8
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/KaclsKeyMetadata.php
@@ -0,0 +1,60 @@
+kaclsData = $kaclsData;
+ }
+ /**
+ * @return string
+ */
+ public function getKaclsData()
+ {
+ return $this->kaclsData;
+ }
+ /**
+ * @param string
+ */
+ public function setKaclsUri($kaclsUri)
+ {
+ $this->kaclsUri = $kaclsUri;
+ }
+ /**
+ * @return string
+ */
+ public function getKaclsUri()
+ {
+ return $this->kaclsUri;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(KaclsKeyMetadata::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_KaclsKeyMetadata');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Label.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Label.php
new file mode 100755
index 00000000..69f8f5cb
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Label.php
@@ -0,0 +1,202 @@
+color = $color;
+ }
+ /**
+ * @return LabelColor
+ */
+ public function getColor()
+ {
+ return $this->color;
+ }
+ /**
+ * @param string
+ */
+ public function setId($id)
+ {
+ $this->id = $id;
+ }
+ /**
+ * @return string
+ */
+ public function getId()
+ {
+ return $this->id;
+ }
+ /**
+ * @param string
+ */
+ public function setLabelListVisibility($labelListVisibility)
+ {
+ $this->labelListVisibility = $labelListVisibility;
+ }
+ /**
+ * @return string
+ */
+ public function getLabelListVisibility()
+ {
+ return $this->labelListVisibility;
+ }
+ /**
+ * @param string
+ */
+ public function setMessageListVisibility($messageListVisibility)
+ {
+ $this->messageListVisibility = $messageListVisibility;
+ }
+ /**
+ * @return string
+ */
+ public function getMessageListVisibility()
+ {
+ return $this->messageListVisibility;
+ }
+ /**
+ * @param int
+ */
+ public function setMessagesTotal($messagesTotal)
+ {
+ $this->messagesTotal = $messagesTotal;
+ }
+ /**
+ * @return int
+ */
+ public function getMessagesTotal()
+ {
+ return $this->messagesTotal;
+ }
+ /**
+ * @param int
+ */
+ public function setMessagesUnread($messagesUnread)
+ {
+ $this->messagesUnread = $messagesUnread;
+ }
+ /**
+ * @return int
+ */
+ public function getMessagesUnread()
+ {
+ return $this->messagesUnread;
+ }
+ /**
+ * @param string
+ */
+ public function setName($name)
+ {
+ $this->name = $name;
+ }
+ /**
+ * @return string
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+ /**
+ * @param int
+ */
+ public function setThreadsTotal($threadsTotal)
+ {
+ $this->threadsTotal = $threadsTotal;
+ }
+ /**
+ * @return int
+ */
+ public function getThreadsTotal()
+ {
+ return $this->threadsTotal;
+ }
+ /**
+ * @param int
+ */
+ public function setThreadsUnread($threadsUnread)
+ {
+ $this->threadsUnread = $threadsUnread;
+ }
+ /**
+ * @return int
+ */
+ public function getThreadsUnread()
+ {
+ return $this->threadsUnread;
+ }
+ /**
+ * @param string
+ */
+ public function setType($type)
+ {
+ $this->type = $type;
+ }
+ /**
+ * @return string
+ */
+ public function getType()
+ {
+ return $this->type;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(Label::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_Label');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/LabelColor.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/LabelColor.php
new file mode 100755
index 00000000..bc826593
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/LabelColor.php
@@ -0,0 +1,60 @@
+backgroundColor = $backgroundColor;
+ }
+ /**
+ * @return string
+ */
+ public function getBackgroundColor()
+ {
+ return $this->backgroundColor;
+ }
+ /**
+ * @param string
+ */
+ public function setTextColor($textColor)
+ {
+ $this->textColor = $textColor;
+ }
+ /**
+ * @return string
+ */
+ public function getTextColor()
+ {
+ return $this->textColor;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(LabelColor::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_LabelColor');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/LanguageSettings.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/LanguageSettings.php
new file mode 100755
index 00000000..9053063d
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/LanguageSettings.php
@@ -0,0 +1,42 @@
+displayLanguage = $displayLanguage;
+ }
+ /**
+ * @return string
+ */
+ public function getDisplayLanguage()
+ {
+ return $this->displayLanguage;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(LanguageSettings::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_LanguageSettings');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ListCseIdentitiesResponse.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ListCseIdentitiesResponse.php
new file mode 100755
index 00000000..340c42d4
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ListCseIdentitiesResponse.php
@@ -0,0 +1,59 @@
+cseIdentities = $cseIdentities;
+ }
+ /**
+ * @return CseIdentity[]
+ */
+ public function getCseIdentities()
+ {
+ return $this->cseIdentities;
+ }
+ /**
+ * @param string
+ */
+ public function setNextPageToken($nextPageToken)
+ {
+ $this->nextPageToken = $nextPageToken;
+ }
+ /**
+ * @return string
+ */
+ public function getNextPageToken()
+ {
+ return $this->nextPageToken;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(ListCseIdentitiesResponse::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_ListCseIdentitiesResponse');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ListCseKeyPairsResponse.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ListCseKeyPairsResponse.php
new file mode 100755
index 00000000..b503c9c9
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ListCseKeyPairsResponse.php
@@ -0,0 +1,59 @@
+cseKeyPairs = $cseKeyPairs;
+ }
+ /**
+ * @return CseKeyPair[]
+ */
+ public function getCseKeyPairs()
+ {
+ return $this->cseKeyPairs;
+ }
+ /**
+ * @param string
+ */
+ public function setNextPageToken($nextPageToken)
+ {
+ $this->nextPageToken = $nextPageToken;
+ }
+ /**
+ * @return string
+ */
+ public function getNextPageToken()
+ {
+ return $this->nextPageToken;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(ListCseKeyPairsResponse::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_ListCseKeyPairsResponse');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ListDelegatesResponse.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ListDelegatesResponse.php
new file mode 100755
index 00000000..448516d9
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ListDelegatesResponse.php
@@ -0,0 +1,41 @@
+delegates = $delegates;
+ }
+ /**
+ * @return Delegate[]
+ */
+ public function getDelegates()
+ {
+ return $this->delegates;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(ListDelegatesResponse::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_ListDelegatesResponse');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ListDraftsResponse.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ListDraftsResponse.php
new file mode 100755
index 00000000..054fb29c
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ListDraftsResponse.php
@@ -0,0 +1,77 @@
+drafts = $drafts;
+ }
+ /**
+ * @return Draft[]
+ */
+ public function getDrafts()
+ {
+ return $this->drafts;
+ }
+ /**
+ * @param string
+ */
+ public function setNextPageToken($nextPageToken)
+ {
+ $this->nextPageToken = $nextPageToken;
+ }
+ /**
+ * @return string
+ */
+ public function getNextPageToken()
+ {
+ return $this->nextPageToken;
+ }
+ /**
+ * @param string
+ */
+ public function setResultSizeEstimate($resultSizeEstimate)
+ {
+ $this->resultSizeEstimate = $resultSizeEstimate;
+ }
+ /**
+ * @return string
+ */
+ public function getResultSizeEstimate()
+ {
+ return $this->resultSizeEstimate;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(ListDraftsResponse::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_ListDraftsResponse');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ListFiltersResponse.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ListFiltersResponse.php
new file mode 100755
index 00000000..7f411663
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ListFiltersResponse.php
@@ -0,0 +1,41 @@
+filter = $filter;
+ }
+ /**
+ * @return Filter[]
+ */
+ public function getFilter()
+ {
+ return $this->filter;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(ListFiltersResponse::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_ListFiltersResponse');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ListForwardingAddressesResponse.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ListForwardingAddressesResponse.php
new file mode 100755
index 00000000..c970118a
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ListForwardingAddressesResponse.php
@@ -0,0 +1,41 @@
+forwardingAddresses = $forwardingAddresses;
+ }
+ /**
+ * @return ForwardingAddress[]
+ */
+ public function getForwardingAddresses()
+ {
+ return $this->forwardingAddresses;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(ListForwardingAddressesResponse::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_ListForwardingAddressesResponse');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ListHistoryResponse.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ListHistoryResponse.php
new file mode 100755
index 00000000..523a4b37
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ListHistoryResponse.php
@@ -0,0 +1,77 @@
+history = $history;
+ }
+ /**
+ * @return History[]
+ */
+ public function getHistory()
+ {
+ return $this->history;
+ }
+ /**
+ * @param string
+ */
+ public function setHistoryId($historyId)
+ {
+ $this->historyId = $historyId;
+ }
+ /**
+ * @return string
+ */
+ public function getHistoryId()
+ {
+ return $this->historyId;
+ }
+ /**
+ * @param string
+ */
+ public function setNextPageToken($nextPageToken)
+ {
+ $this->nextPageToken = $nextPageToken;
+ }
+ /**
+ * @return string
+ */
+ public function getNextPageToken()
+ {
+ return $this->nextPageToken;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(ListHistoryResponse::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_ListHistoryResponse');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ListLabelsResponse.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ListLabelsResponse.php
new file mode 100755
index 00000000..164103bd
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ListLabelsResponse.php
@@ -0,0 +1,41 @@
+labels = $labels;
+ }
+ /**
+ * @return Label[]
+ */
+ public function getLabels()
+ {
+ return $this->labels;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(ListLabelsResponse::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_ListLabelsResponse');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ListMessagesResponse.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ListMessagesResponse.php
new file mode 100755
index 00000000..43814e1e
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ListMessagesResponse.php
@@ -0,0 +1,77 @@
+messages = $messages;
+ }
+ /**
+ * @return Message[]
+ */
+ public function getMessages()
+ {
+ return $this->messages;
+ }
+ /**
+ * @param string
+ */
+ public function setNextPageToken($nextPageToken)
+ {
+ $this->nextPageToken = $nextPageToken;
+ }
+ /**
+ * @return string
+ */
+ public function getNextPageToken()
+ {
+ return $this->nextPageToken;
+ }
+ /**
+ * @param string
+ */
+ public function setResultSizeEstimate($resultSizeEstimate)
+ {
+ $this->resultSizeEstimate = $resultSizeEstimate;
+ }
+ /**
+ * @return string
+ */
+ public function getResultSizeEstimate()
+ {
+ return $this->resultSizeEstimate;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(ListMessagesResponse::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_ListMessagesResponse');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ListSendAsResponse.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ListSendAsResponse.php
new file mode 100755
index 00000000..8bd2ef67
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ListSendAsResponse.php
@@ -0,0 +1,41 @@
+sendAs = $sendAs;
+ }
+ /**
+ * @return SendAs[]
+ */
+ public function getSendAs()
+ {
+ return $this->sendAs;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(ListSendAsResponse::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_ListSendAsResponse');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ListSmimeInfoResponse.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ListSmimeInfoResponse.php
new file mode 100755
index 00000000..96da7839
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ListSmimeInfoResponse.php
@@ -0,0 +1,41 @@
+smimeInfo = $smimeInfo;
+ }
+ /**
+ * @return SmimeInfo[]
+ */
+ public function getSmimeInfo()
+ {
+ return $this->smimeInfo;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(ListSmimeInfoResponse::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_ListSmimeInfoResponse');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ListThreadsResponse.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ListThreadsResponse.php
new file mode 100755
index 00000000..a80bf377
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ListThreadsResponse.php
@@ -0,0 +1,77 @@
+nextPageToken = $nextPageToken;
+ }
+ /**
+ * @return string
+ */
+ public function getNextPageToken()
+ {
+ return $this->nextPageToken;
+ }
+ /**
+ * @param string
+ */
+ public function setResultSizeEstimate($resultSizeEstimate)
+ {
+ $this->resultSizeEstimate = $resultSizeEstimate;
+ }
+ /**
+ * @return string
+ */
+ public function getResultSizeEstimate()
+ {
+ return $this->resultSizeEstimate;
+ }
+ /**
+ * @param Thread[]
+ */
+ public function setThreads($threads)
+ {
+ $this->threads = $threads;
+ }
+ /**
+ * @return Thread[]
+ */
+ public function getThreads()
+ {
+ return $this->threads;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(ListThreadsResponse::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_ListThreadsResponse');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Message.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Message.php
new file mode 100755
index 00000000..8b7c84a9
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Message.php
@@ -0,0 +1,185 @@
+historyId = $historyId;
+ }
+ /**
+ * @return string
+ */
+ public function getHistoryId()
+ {
+ return $this->historyId;
+ }
+ /**
+ * @param string
+ */
+ public function setId($id)
+ {
+ $this->id = $id;
+ }
+ /**
+ * @return string
+ */
+ public function getId()
+ {
+ return $this->id;
+ }
+ /**
+ * @param string
+ */
+ public function setInternalDate($internalDate)
+ {
+ $this->internalDate = $internalDate;
+ }
+ /**
+ * @return string
+ */
+ public function getInternalDate()
+ {
+ return $this->internalDate;
+ }
+ /**
+ * @param string[]
+ */
+ public function setLabelIds($labelIds)
+ {
+ $this->labelIds = $labelIds;
+ }
+ /**
+ * @return string[]
+ */
+ public function getLabelIds()
+ {
+ return $this->labelIds;
+ }
+ /**
+ * @param MessagePart
+ */
+ public function setPayload(MessagePart $payload)
+ {
+ $this->payload = $payload;
+ }
+ /**
+ * @return MessagePart
+ */
+ public function getPayload()
+ {
+ return $this->payload;
+ }
+ /**
+ * @param string
+ */
+ public function setRaw($raw)
+ {
+ $this->raw = $raw;
+ }
+ /**
+ * @return string
+ */
+ public function getRaw()
+ {
+ return $this->raw;
+ }
+ /**
+ * @param int
+ */
+ public function setSizeEstimate($sizeEstimate)
+ {
+ $this->sizeEstimate = $sizeEstimate;
+ }
+ /**
+ * @return int
+ */
+ public function getSizeEstimate()
+ {
+ return $this->sizeEstimate;
+ }
+ /**
+ * @param string
+ */
+ public function setSnippet($snippet)
+ {
+ $this->snippet = $snippet;
+ }
+ /**
+ * @return string
+ */
+ public function getSnippet()
+ {
+ return $this->snippet;
+ }
+ /**
+ * @param string
+ */
+ public function setThreadId($threadId)
+ {
+ $this->threadId = $threadId;
+ }
+ /**
+ * @return string
+ */
+ public function getThreadId()
+ {
+ return $this->threadId;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(Message::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_Message');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/MessagePart.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/MessagePart.php
new file mode 100755
index 00000000..1336f2be
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/MessagePart.php
@@ -0,0 +1,127 @@
+body = $body;
+ }
+ /**
+ * @return MessagePartBody
+ */
+ public function getBody()
+ {
+ return $this->body;
+ }
+ /**
+ * @param string
+ */
+ public function setFilename($filename)
+ {
+ $this->filename = $filename;
+ }
+ /**
+ * @return string
+ */
+ public function getFilename()
+ {
+ return $this->filename;
+ }
+ /**
+ * @param MessagePartHeader[]
+ */
+ public function setHeaders($headers)
+ {
+ $this->headers = $headers;
+ }
+ /**
+ * @return MessagePartHeader[]
+ */
+ public function getHeaders()
+ {
+ return $this->headers;
+ }
+ /**
+ * @param string
+ */
+ public function setMimeType($mimeType)
+ {
+ $this->mimeType = $mimeType;
+ }
+ /**
+ * @return string
+ */
+ public function getMimeType()
+ {
+ return $this->mimeType;
+ }
+ /**
+ * @param string
+ */
+ public function setPartId($partId)
+ {
+ $this->partId = $partId;
+ }
+ /**
+ * @return string
+ */
+ public function getPartId()
+ {
+ return $this->partId;
+ }
+ /**
+ * @param MessagePart[]
+ */
+ public function setParts($parts)
+ {
+ $this->parts = $parts;
+ }
+ /**
+ * @return MessagePart[]
+ */
+ public function getParts()
+ {
+ return $this->parts;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(MessagePart::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_MessagePart');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/MessagePartBody.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/MessagePartBody.php
new file mode 100755
index 00000000..d98bf833
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/MessagePartBody.php
@@ -0,0 +1,78 @@
+attachmentId = $attachmentId;
+ }
+ /**
+ * @return string
+ */
+ public function getAttachmentId()
+ {
+ return $this->attachmentId;
+ }
+ /**
+ * @param string
+ */
+ public function setData($data)
+ {
+ $this->data = $data;
+ }
+ /**
+ * @return string
+ */
+ public function getData()
+ {
+ return $this->data;
+ }
+ /**
+ * @param int
+ */
+ public function setSize($size)
+ {
+ $this->size = $size;
+ }
+ /**
+ * @return int
+ */
+ public function getSize()
+ {
+ return $this->size;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(MessagePartBody::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_MessagePartBody');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/MessagePartHeader.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/MessagePartHeader.php
new file mode 100755
index 00000000..d11d39d0
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/MessagePartHeader.php
@@ -0,0 +1,60 @@
+name = $name;
+ }
+ /**
+ * @return string
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+ /**
+ * @param string
+ */
+ public function setValue($value)
+ {
+ $this->value = $value;
+ }
+ /**
+ * @return string
+ */
+ public function getValue()
+ {
+ return $this->value;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(MessagePartHeader::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_MessagePartHeader');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ModifyMessageRequest.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ModifyMessageRequest.php
new file mode 100755
index 00000000..69243935
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ModifyMessageRequest.php
@@ -0,0 +1,61 @@
+addLabelIds = $addLabelIds;
+ }
+ /**
+ * @return string[]
+ */
+ public function getAddLabelIds()
+ {
+ return $this->addLabelIds;
+ }
+ /**
+ * @param string[]
+ */
+ public function setRemoveLabelIds($removeLabelIds)
+ {
+ $this->removeLabelIds = $removeLabelIds;
+ }
+ /**
+ * @return string[]
+ */
+ public function getRemoveLabelIds()
+ {
+ return $this->removeLabelIds;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(ModifyMessageRequest::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_ModifyMessageRequest');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ModifyThreadRequest.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ModifyThreadRequest.php
new file mode 100755
index 00000000..7a3199a7
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ModifyThreadRequest.php
@@ -0,0 +1,61 @@
+addLabelIds = $addLabelIds;
+ }
+ /**
+ * @return string[]
+ */
+ public function getAddLabelIds()
+ {
+ return $this->addLabelIds;
+ }
+ /**
+ * @param string[]
+ */
+ public function setRemoveLabelIds($removeLabelIds)
+ {
+ $this->removeLabelIds = $removeLabelIds;
+ }
+ /**
+ * @return string[]
+ */
+ public function getRemoveLabelIds()
+ {
+ return $this->removeLabelIds;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(ModifyThreadRequest::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_ModifyThreadRequest');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ObliterateCseKeyPairRequest.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ObliterateCseKeyPairRequest.php
new file mode 100755
index 00000000..0d2160df
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/ObliterateCseKeyPairRequest.php
@@ -0,0 +1,24 @@
+description = $description;
+ }
+ /**
+ * @return string
+ */
+ public function getDescription()
+ {
+ return $this->description;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(PivKeyMetadata::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_PivKeyMetadata');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/PopSettings.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/PopSettings.php
new file mode 100755
index 00000000..235f0cb0
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/PopSettings.php
@@ -0,0 +1,60 @@
+accessWindow = $accessWindow;
+ }
+ /**
+ * @return string
+ */
+ public function getAccessWindow()
+ {
+ return $this->accessWindow;
+ }
+ /**
+ * @param string
+ */
+ public function setDisposition($disposition)
+ {
+ $this->disposition = $disposition;
+ }
+ /**
+ * @return string
+ */
+ public function getDisposition()
+ {
+ return $this->disposition;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(PopSettings::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_PopSettings');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Profile.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Profile.php
new file mode 100755
index 00000000..b49f6cdd
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Profile.php
@@ -0,0 +1,96 @@
+emailAddress = $emailAddress;
+ }
+ /**
+ * @return string
+ */
+ public function getEmailAddress()
+ {
+ return $this->emailAddress;
+ }
+ /**
+ * @param string
+ */
+ public function setHistoryId($historyId)
+ {
+ $this->historyId = $historyId;
+ }
+ /**
+ * @return string
+ */
+ public function getHistoryId()
+ {
+ return $this->historyId;
+ }
+ /**
+ * @param int
+ */
+ public function setMessagesTotal($messagesTotal)
+ {
+ $this->messagesTotal = $messagesTotal;
+ }
+ /**
+ * @return int
+ */
+ public function getMessagesTotal()
+ {
+ return $this->messagesTotal;
+ }
+ /**
+ * @param int
+ */
+ public function setThreadsTotal($threadsTotal)
+ {
+ $this->threadsTotal = $threadsTotal;
+ }
+ /**
+ * @return int
+ */
+ public function getThreadsTotal()
+ {
+ return $this->threadsTotal;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(Profile::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_Profile');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/Users.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/Users.php
new file mode 100755
index 00000000..40cc99b9
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/Users.php
@@ -0,0 +1,83 @@
+
+ * $gmailService = new Google\Service\Gmail(...);
+ * $users = $gmailService->users;
+ *
+ */
+class Users extends \WPMailSMTP\Vendor\Google\Service\Resource
+{
+ /**
+ * Gets the current user's Gmail profile. (users.getProfile)
+ *
+ * @param string $userId The user's email address. The special value `me` can be
+ * used to indicate the authenticated user.
+ * @param array $optParams Optional parameters.
+ *
+ * @opt_param bool temporaryEeccBypass
+ * @return Profile
+ * @throws \Google\Service\Exception
+ */
+ public function getProfile($userId, $optParams = [])
+ {
+ $params = ['userId' => $userId];
+ $params = \array_merge($params, $optParams);
+ return $this->call('getProfile', [$params], Profile::class);
+ }
+ /**
+ * Stop receiving push notifications for the given user mailbox. (users.stop)
+ *
+ * @param string $userId The user's email address. The special value `me` can be
+ * used to indicate the authenticated user.
+ * @param array $optParams Optional parameters.
+ * @throws \Google\Service\Exception
+ */
+ public function stop($userId, $optParams = [])
+ {
+ $params = ['userId' => $userId];
+ $params = \array_merge($params, $optParams);
+ return $this->call('stop', [$params]);
+ }
+ /**
+ * Set up or update a push notification watch on the given user mailbox.
+ * (users.watch)
+ *
+ * @param string $userId The user's email address. The special value `me` can be
+ * used to indicate the authenticated user.
+ * @param WatchRequest $postBody
+ * @param array $optParams Optional parameters.
+ * @return WatchResponse
+ * @throws \Google\Service\Exception
+ */
+ public function watch($userId, WatchRequest $postBody, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'postBody' => $postBody];
+ $params = \array_merge($params, $optParams);
+ return $this->call('watch', [$params], WatchResponse::class);
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(Users::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_Resource_Users');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/UsersDrafts.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/UsersDrafts.php
new file mode 100755
index 00000000..dcceee2b
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/UsersDrafts.php
@@ -0,0 +1,144 @@
+
+ * $gmailService = new Google\Service\Gmail(...);
+ * $drafts = $gmailService->users_drafts;
+ *
+ */
+class UsersDrafts extends \WPMailSMTP\Vendor\Google\Service\Resource
+{
+ /**
+ * Creates a new draft with the `DRAFT` label. (drafts.create)
+ *
+ * @param string $userId The user's email address. The special value `me` can be
+ * used to indicate the authenticated user.
+ * @param Draft $postBody
+ * @param array $optParams Optional parameters.
+ * @return Draft
+ * @throws \Google\Service\Exception
+ */
+ public function create($userId, Draft $postBody, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'postBody' => $postBody];
+ $params = \array_merge($params, $optParams);
+ return $this->call('create', [$params], Draft::class);
+ }
+ /**
+ * Immediately and permanently deletes the specified draft. Does not simply
+ * trash it. (drafts.delete)
+ *
+ * @param string $userId The user's email address. The special value `me` can be
+ * used to indicate the authenticated user.
+ * @param string $id The ID of the draft to delete.
+ * @param array $optParams Optional parameters.
+ * @throws \Google\Service\Exception
+ */
+ public function delete($userId, $id, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'id' => $id];
+ $params = \array_merge($params, $optParams);
+ return $this->call('delete', [$params]);
+ }
+ /**
+ * Gets the specified draft. (drafts.get)
+ *
+ * @param string $userId The user's email address. The special value `me` can be
+ * used to indicate the authenticated user.
+ * @param string $id The ID of the draft to retrieve.
+ * @param array $optParams Optional parameters.
+ *
+ * @opt_param string format The format to return the draft in.
+ * @return Draft
+ * @throws \Google\Service\Exception
+ */
+ public function get($userId, $id, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'id' => $id];
+ $params = \array_merge($params, $optParams);
+ return $this->call('get', [$params], Draft::class);
+ }
+ /**
+ * Lists the drafts in the user's mailbox. (drafts.listUsersDrafts)
+ *
+ * @param string $userId The user's email address. The special value `me` can be
+ * used to indicate the authenticated user.
+ * @param array $optParams Optional parameters.
+ *
+ * @opt_param bool includeSpamTrash Include drafts from `SPAM` and `TRASH` in
+ * the results.
+ * @opt_param string maxResults Maximum number of drafts to return. This field
+ * defaults to 100. The maximum allowed value for this field is 500.
+ * @opt_param string pageToken Page token to retrieve a specific page of results
+ * in the list.
+ * @opt_param string q Only return draft messages matching the specified query.
+ * Supports the same query format as the Gmail search box. For example,
+ * `"from:someuser@example.com rfc822msgid: is:unread"`.
+ * @return ListDraftsResponse
+ * @throws \Google\Service\Exception
+ */
+ public function listUsersDrafts($userId, $optParams = [])
+ {
+ $params = ['userId' => $userId];
+ $params = \array_merge($params, $optParams);
+ return $this->call('list', [$params], ListDraftsResponse::class);
+ }
+ /**
+ * Sends the specified, existing draft to the recipients in the `To`, `Cc`, and
+ * `Bcc` headers. (drafts.send)
+ *
+ * @param string $userId The user's email address. The special value `me` can be
+ * used to indicate the authenticated user.
+ * @param Draft $postBody
+ * @param array $optParams Optional parameters.
+ * @return Message
+ * @throws \Google\Service\Exception
+ */
+ public function send($userId, Draft $postBody, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'postBody' => $postBody];
+ $params = \array_merge($params, $optParams);
+ return $this->call('send', [$params], Message::class);
+ }
+ /**
+ * Replaces a draft's content. (drafts.update)
+ *
+ * @param string $userId The user's email address. The special value `me` can be
+ * used to indicate the authenticated user.
+ * @param string $id The ID of the draft to update.
+ * @param Draft $postBody
+ * @param array $optParams Optional parameters.
+ * @return Draft
+ * @throws \Google\Service\Exception
+ */
+ public function update($userId, $id, Draft $postBody, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'id' => $id, 'postBody' => $postBody];
+ $params = \array_merge($params, $optParams);
+ return $this->call('update', [$params], Draft::class);
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(UsersDrafts::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_Resource_UsersDrafts');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/UsersHistory.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/UsersHistory.php
new file mode 100755
index 00000000..30fa5e0c
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/UsersHistory.php
@@ -0,0 +1,68 @@
+
+ * $gmailService = new Google\Service\Gmail(...);
+ * $history = $gmailService->users_history;
+ *
+ */
+class UsersHistory extends \WPMailSMTP\Vendor\Google\Service\Resource
+{
+ /**
+ * Lists the history of all changes to the given mailbox. History results are
+ * returned in chronological order (increasing `historyId`).
+ * (history.listUsersHistory)
+ *
+ * @param string $userId The user's email address. The special value `me` can be
+ * used to indicate the authenticated user.
+ * @param array $optParams Optional parameters.
+ *
+ * @opt_param string historyTypes History types to be returned by the function
+ * @opt_param string labelId Only return messages with a label matching the ID.
+ * @opt_param string maxResults Maximum number of history records to return.
+ * This field defaults to 100. The maximum allowed value for this field is 500.
+ * @opt_param string pageToken Page token to retrieve a specific page of results
+ * in the list.
+ * @opt_param string startHistoryId Required. Returns history records after the
+ * specified `startHistoryId`. The supplied `startHistoryId` should be obtained
+ * from the `historyId` of a message, thread, or previous `list` response.
+ * History IDs increase chronologically but are not contiguous with random gaps
+ * in between valid IDs. Supplying an invalid or out of date `startHistoryId`
+ * typically returns an `HTTP 404` error code. A `historyId` is typically valid
+ * for at least a week, but in some rare circumstances may be valid for only a
+ * few hours. If you receive an `HTTP 404` error response, your application
+ * should perform a full sync. If you receive no `nextPageToken` in the
+ * response, there are no updates to retrieve and you can store the returned
+ * `historyId` for a future request.
+ * @return ListHistoryResponse
+ * @throws \Google\Service\Exception
+ */
+ public function listUsersHistory($userId, $optParams = [])
+ {
+ $params = ['userId' => $userId];
+ $params = \array_merge($params, $optParams);
+ return $this->call('list', [$params], ListHistoryResponse::class);
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(UsersHistory::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_Resource_UsersHistory');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/UsersLabels.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/UsersLabels.php
new file mode 100755
index 00000000..0e84be8a
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/UsersLabels.php
@@ -0,0 +1,131 @@
+
+ * $gmailService = new Google\Service\Gmail(...);
+ * $labels = $gmailService->users_labels;
+ *
+ */
+class UsersLabels extends \WPMailSMTP\Vendor\Google\Service\Resource
+{
+ /**
+ * Creates a new label. (labels.create)
+ *
+ * @param string $userId The user's email address. The special value `me` can be
+ * used to indicate the authenticated user.
+ * @param Label $postBody
+ * @param array $optParams Optional parameters.
+ * @return Label
+ * @throws \Google\Service\Exception
+ */
+ public function create($userId, Label $postBody, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'postBody' => $postBody];
+ $params = \array_merge($params, $optParams);
+ return $this->call('create', [$params], Label::class);
+ }
+ /**
+ * Immediately and permanently deletes the specified label and removes it from
+ * any messages and threads that it is applied to. (labels.delete)
+ *
+ * @param string $userId The user's email address. The special value `me` can be
+ * used to indicate the authenticated user.
+ * @param string $id The ID of the label to delete.
+ * @param array $optParams Optional parameters.
+ * @throws \Google\Service\Exception
+ */
+ public function delete($userId, $id, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'id' => $id];
+ $params = \array_merge($params, $optParams);
+ return $this->call('delete', [$params]);
+ }
+ /**
+ * Gets the specified label. (labels.get)
+ *
+ * @param string $userId The user's email address. The special value `me` can be
+ * used to indicate the authenticated user.
+ * @param string $id The ID of the label to retrieve.
+ * @param array $optParams Optional parameters.
+ * @return Label
+ * @throws \Google\Service\Exception
+ */
+ public function get($userId, $id, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'id' => $id];
+ $params = \array_merge($params, $optParams);
+ return $this->call('get', [$params], Label::class);
+ }
+ /**
+ * Lists all labels in the user's mailbox. (labels.listUsersLabels)
+ *
+ * @param string $userId The user's email address. The special value `me` can be
+ * used to indicate the authenticated user.
+ * @param array $optParams Optional parameters.
+ * @return ListLabelsResponse
+ * @throws \Google\Service\Exception
+ */
+ public function listUsersLabels($userId, $optParams = [])
+ {
+ $params = ['userId' => $userId];
+ $params = \array_merge($params, $optParams);
+ return $this->call('list', [$params], ListLabelsResponse::class);
+ }
+ /**
+ * Patch the specified label. (labels.patch)
+ *
+ * @param string $userId The user's email address. The special value `me` can be
+ * used to indicate the authenticated user.
+ * @param string $id The ID of the label to update.
+ * @param Label $postBody
+ * @param array $optParams Optional parameters.
+ * @return Label
+ * @throws \Google\Service\Exception
+ */
+ public function patch($userId, $id, Label $postBody, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'id' => $id, 'postBody' => $postBody];
+ $params = \array_merge($params, $optParams);
+ return $this->call('patch', [$params], Label::class);
+ }
+ /**
+ * Updates the specified label. (labels.update)
+ *
+ * @param string $userId The user's email address. The special value `me` can be
+ * used to indicate the authenticated user.
+ * @param string $id The ID of the label to update.
+ * @param Label $postBody
+ * @param array $optParams Optional parameters.
+ * @return Label
+ * @throws \Google\Service\Exception
+ */
+ public function update($userId, $id, Label $postBody, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'id' => $id, 'postBody' => $postBody];
+ $params = \array_merge($params, $optParams);
+ return $this->call('update', [$params], Label::class);
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(UsersLabels::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_Resource_UsersLabels');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/UsersMessages.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/UsersMessages.php
new file mode 100755
index 00000000..f66f85a0
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/UsersMessages.php
@@ -0,0 +1,261 @@
+
+ * $gmailService = new Google\Service\Gmail(...);
+ * $messages = $gmailService->users_messages;
+ *
+ */
+class UsersMessages extends \WPMailSMTP\Vendor\Google\Service\Resource
+{
+ /**
+ * Deletes many messages by message ID. Provides no guarantees that messages
+ * were not already deleted or even existed at all. (messages.batchDelete)
+ *
+ * @param string $userId The user's email address. The special value `me` can be
+ * used to indicate the authenticated user.
+ * @param BatchDeleteMessagesRequest $postBody
+ * @param array $optParams Optional parameters.
+ * @throws \Google\Service\Exception
+ */
+ public function batchDelete($userId, BatchDeleteMessagesRequest $postBody, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'postBody' => $postBody];
+ $params = \array_merge($params, $optParams);
+ return $this->call('batchDelete', [$params]);
+ }
+ /**
+ * Modifies the labels on the specified messages. (messages.batchModify)
+ *
+ * @param string $userId The user's email address. The special value `me` can be
+ * used to indicate the authenticated user.
+ * @param BatchModifyMessagesRequest $postBody
+ * @param array $optParams Optional parameters.
+ * @throws \Google\Service\Exception
+ */
+ public function batchModify($userId, BatchModifyMessagesRequest $postBody, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'postBody' => $postBody];
+ $params = \array_merge($params, $optParams);
+ return $this->call('batchModify', [$params]);
+ }
+ /**
+ * Immediately and permanently deletes the specified message. This operation
+ * cannot be undone. Prefer `messages.trash` instead. (messages.delete)
+ *
+ * @param string $userId The user's email address. The special value `me` can be
+ * used to indicate the authenticated user.
+ * @param string $id The ID of the message to delete.
+ * @param array $optParams Optional parameters.
+ * @throws \Google\Service\Exception
+ */
+ public function delete($userId, $id, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'id' => $id];
+ $params = \array_merge($params, $optParams);
+ return $this->call('delete', [$params]);
+ }
+ /**
+ * Gets the specified message. (messages.get)
+ *
+ * @param string $userId The user's email address. The special value `me` can be
+ * used to indicate the authenticated user.
+ * @param string $id The ID of the message to retrieve. This ID is usually
+ * retrieved using `messages.list`. The ID is also contained in the result when
+ * a message is inserted (`messages.insert`) or imported (`messages.import`).
+ * @param array $optParams Optional parameters.
+ *
+ * @opt_param string format The format to return the message in.
+ * @opt_param string metadataHeaders When given and format is `METADATA`, only
+ * include headers specified.
+ * @opt_param bool temporaryEeccBypass
+ * @return Message
+ * @throws \Google\Service\Exception
+ */
+ public function get($userId, $id, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'id' => $id];
+ $params = \array_merge($params, $optParams);
+ return $this->call('get', [$params], Message::class);
+ }
+ /**
+ * Imports a message into only this user's mailbox, with standard email delivery
+ * scanning and classification similar to receiving via SMTP. This method
+ * doesn't perform SPF checks, so it might not work for some spam messages, such
+ * as those attempting to perform domain spoofing. This method does not send a
+ * message. (messages.import)
+ *
+ * @param string $userId The user's email address. The special value `me` can be
+ * used to indicate the authenticated user.
+ * @param Message $postBody
+ * @param array $optParams Optional parameters.
+ *
+ * @opt_param bool deleted Mark the email as permanently deleted (not TRASH) and
+ * only visible in Google Vault to a Vault administrator. Only used for Google
+ * Workspace accounts.
+ * @opt_param string internalDateSource Source for Gmail's internal date of the
+ * message.
+ * @opt_param bool neverMarkSpam Ignore the Gmail spam classifier decision and
+ * never mark this email as SPAM in the mailbox.
+ * @opt_param bool processForCalendar Process calendar invites in the email and
+ * add any extracted meetings to the Google Calendar for this user.
+ * @return Message
+ * @throws \Google\Service\Exception
+ */
+ public function import($userId, Message $postBody, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'postBody' => $postBody];
+ $params = \array_merge($params, $optParams);
+ return $this->call('import', [$params], Message::class);
+ }
+ /**
+ * Directly inserts a message into only this user's mailbox similar to `IMAP
+ * APPEND`, bypassing most scanning and classification. Does not send a message.
+ * (messages.insert)
+ *
+ * @param string $userId The user's email address. The special value `me` can be
+ * used to indicate the authenticated user.
+ * @param Message $postBody
+ * @param array $optParams Optional parameters.
+ *
+ * @opt_param bool deleted Mark the email as permanently deleted (not TRASH) and
+ * only visible in Google Vault to a Vault administrator. Only used for Google
+ * Workspace accounts.
+ * @opt_param string internalDateSource Source for Gmail's internal date of the
+ * message.
+ * @return Message
+ * @throws \Google\Service\Exception
+ */
+ public function insert($userId, Message $postBody, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'postBody' => $postBody];
+ $params = \array_merge($params, $optParams);
+ return $this->call('insert', [$params], Message::class);
+ }
+ /**
+ * Lists the messages in the user's mailbox. (messages.listUsersMessages)
+ *
+ * @param string $userId The user's email address. The special value `me` can be
+ * used to indicate the authenticated user.
+ * @param array $optParams Optional parameters.
+ *
+ * @opt_param bool includeSpamTrash Include messages from `SPAM` and `TRASH` in
+ * the results.
+ * @opt_param string labelIds Only return messages with labels that match all of
+ * the specified label IDs. Messages in a thread might have labels that other
+ * messages in the same thread don't have. To learn more, see [Manage labels on
+ * messages and threads](https://developers.google.com/gmail/api/guides/labels#m
+ * anage_labels_on_messages_threads).
+ * @opt_param string maxResults Maximum number of messages to return. This field
+ * defaults to 100. The maximum allowed value for this field is 500.
+ * @opt_param string pageToken Page token to retrieve a specific page of results
+ * in the list.
+ * @opt_param string q Only return messages matching the specified query.
+ * Supports the same query format as the Gmail search box. For example,
+ * `"from:someuser@example.com rfc822msgid: is:unread"`. Parameter cannot be
+ * used when accessing the api using the gmail.metadata scope.
+ * @opt_param bool temporaryEeccBypass
+ * @return ListMessagesResponse
+ * @throws \Google\Service\Exception
+ */
+ public function listUsersMessages($userId, $optParams = [])
+ {
+ $params = ['userId' => $userId];
+ $params = \array_merge($params, $optParams);
+ return $this->call('list', [$params], ListMessagesResponse::class);
+ }
+ /**
+ * Modifies the labels on the specified message. (messages.modify)
+ *
+ * @param string $userId The user's email address. The special value `me` can be
+ * used to indicate the authenticated user.
+ * @param string $id The ID of the message to modify.
+ * @param ModifyMessageRequest $postBody
+ * @param array $optParams Optional parameters.
+ * @return Message
+ * @throws \Google\Service\Exception
+ */
+ public function modify($userId, $id, ModifyMessageRequest $postBody, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'id' => $id, 'postBody' => $postBody];
+ $params = \array_merge($params, $optParams);
+ return $this->call('modify', [$params], Message::class);
+ }
+ /**
+ * Sends the specified message to the recipients in the `To`, `Cc`, and `Bcc`
+ * headers. For example usage, see [Sending
+ * email](https://developers.google.com/gmail/api/guides/sending).
+ * (messages.send)
+ *
+ * @param string $userId The user's email address. The special value `me` can be
+ * used to indicate the authenticated user.
+ * @param Message $postBody
+ * @param array $optParams Optional parameters.
+ * @return Message
+ * @throws \Google\Service\Exception
+ */
+ public function send($userId, Message $postBody, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'postBody' => $postBody];
+ $params = \array_merge($params, $optParams);
+ return $this->call('send', [$params], Message::class);
+ }
+ /**
+ * Moves the specified message to the trash. (messages.trash)
+ *
+ * @param string $userId The user's email address. The special value `me` can be
+ * used to indicate the authenticated user.
+ * @param string $id The ID of the message to Trash.
+ * @param array $optParams Optional parameters.
+ * @return Message
+ * @throws \Google\Service\Exception
+ */
+ public function trash($userId, $id, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'id' => $id];
+ $params = \array_merge($params, $optParams);
+ return $this->call('trash', [$params], Message::class);
+ }
+ /**
+ * Removes the specified message from the trash. (messages.untrash)
+ *
+ * @param string $userId The user's email address. The special value `me` can be
+ * used to indicate the authenticated user.
+ * @param string $id The ID of the message to remove from Trash.
+ * @param array $optParams Optional parameters.
+ * @return Message
+ * @throws \Google\Service\Exception
+ */
+ public function untrash($userId, $id, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'id' => $id];
+ $params = \array_merge($params, $optParams);
+ return $this->call('untrash', [$params], Message::class);
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(UsersMessages::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_Resource_UsersMessages');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/UsersMessagesAttachments.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/UsersMessagesAttachments.php
new file mode 100755
index 00000000..d33d6cd3
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/UsersMessagesAttachments.php
@@ -0,0 +1,52 @@
+
+ * $gmailService = new Google\Service\Gmail(...);
+ * $attachments = $gmailService->users_messages_attachments;
+ *
+ */
+class UsersMessagesAttachments extends \WPMailSMTP\Vendor\Google\Service\Resource
+{
+ /**
+ * Gets the specified message attachment. (attachments.get)
+ *
+ * @param string $userId The user's email address. The special value `me` can be
+ * used to indicate the authenticated user.
+ * @param string $messageId The ID of the message containing the attachment.
+ * @param string $id The ID of the attachment.
+ * @param array $optParams Optional parameters.
+ *
+ * @opt_param bool temporaryEeccBypass
+ * @return MessagePartBody
+ * @throws \Google\Service\Exception
+ */
+ public function get($userId, $messageId, $id, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'messageId' => $messageId, 'id' => $id];
+ $params = \array_merge($params, $optParams);
+ return $this->call('get', [$params], MessagePartBody::class);
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(UsersMessagesAttachments::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_Resource_UsersMessagesAttachments');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/UsersSettings.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/UsersSettings.php
new file mode 100755
index 00000000..065bb2cf
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/UsersSettings.php
@@ -0,0 +1,201 @@
+
+ * $gmailService = new Google\Service\Gmail(...);
+ * $settings = $gmailService->users_settings;
+ *
+ */
+class UsersSettings extends \WPMailSMTP\Vendor\Google\Service\Resource
+{
+ /**
+ * Gets the auto-forwarding setting for the specified account.
+ * (settings.getAutoForwarding)
+ *
+ * @param string $userId User's email address. The special value "me" can be
+ * used to indicate the authenticated user.
+ * @param array $optParams Optional parameters.
+ * @return AutoForwarding
+ * @throws \Google\Service\Exception
+ */
+ public function getAutoForwarding($userId, $optParams = [])
+ {
+ $params = ['userId' => $userId];
+ $params = \array_merge($params, $optParams);
+ return $this->call('getAutoForwarding', [$params], AutoForwarding::class);
+ }
+ /**
+ * Gets IMAP settings. (settings.getImap)
+ *
+ * @param string $userId User's email address. The special value "me" can be
+ * used to indicate the authenticated user.
+ * @param array $optParams Optional parameters.
+ * @return ImapSettings
+ * @throws \Google\Service\Exception
+ */
+ public function getImap($userId, $optParams = [])
+ {
+ $params = ['userId' => $userId];
+ $params = \array_merge($params, $optParams);
+ return $this->call('getImap', [$params], ImapSettings::class);
+ }
+ /**
+ * Gets language settings. (settings.getLanguage)
+ *
+ * @param string $userId User's email address. The special value "me" can be
+ * used to indicate the authenticated user.
+ * @param array $optParams Optional parameters.
+ * @return LanguageSettings
+ * @throws \Google\Service\Exception
+ */
+ public function getLanguage($userId, $optParams = [])
+ {
+ $params = ['userId' => $userId];
+ $params = \array_merge($params, $optParams);
+ return $this->call('getLanguage', [$params], LanguageSettings::class);
+ }
+ /**
+ * Gets POP settings. (settings.getPop)
+ *
+ * @param string $userId User's email address. The special value "me" can be
+ * used to indicate the authenticated user.
+ * @param array $optParams Optional parameters.
+ * @return PopSettings
+ * @throws \Google\Service\Exception
+ */
+ public function getPop($userId, $optParams = [])
+ {
+ $params = ['userId' => $userId];
+ $params = \array_merge($params, $optParams);
+ return $this->call('getPop', [$params], PopSettings::class);
+ }
+ /**
+ * Gets vacation responder settings. (settings.getVacation)
+ *
+ * @param string $userId User's email address. The special value "me" can be
+ * used to indicate the authenticated user.
+ * @param array $optParams Optional parameters.
+ * @return VacationSettings
+ * @throws \Google\Service\Exception
+ */
+ public function getVacation($userId, $optParams = [])
+ {
+ $params = ['userId' => $userId];
+ $params = \array_merge($params, $optParams);
+ return $this->call('getVacation', [$params], VacationSettings::class);
+ }
+ /**
+ * Updates the auto-forwarding setting for the specified account. A verified
+ * forwarding address must be specified when auto-forwarding is enabled. This
+ * method is only available to service account clients that have been delegated
+ * domain-wide authority. (settings.updateAutoForwarding)
+ *
+ * @param string $userId User's email address. The special value "me" can be
+ * used to indicate the authenticated user.
+ * @param AutoForwarding $postBody
+ * @param array $optParams Optional parameters.
+ * @return AutoForwarding
+ * @throws \Google\Service\Exception
+ */
+ public function updateAutoForwarding($userId, AutoForwarding $postBody, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'postBody' => $postBody];
+ $params = \array_merge($params, $optParams);
+ return $this->call('updateAutoForwarding', [$params], AutoForwarding::class);
+ }
+ /**
+ * Updates IMAP settings. (settings.updateImap)
+ *
+ * @param string $userId User's email address. The special value "me" can be
+ * used to indicate the authenticated user.
+ * @param ImapSettings $postBody
+ * @param array $optParams Optional parameters.
+ * @return ImapSettings
+ * @throws \Google\Service\Exception
+ */
+ public function updateImap($userId, ImapSettings $postBody, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'postBody' => $postBody];
+ $params = \array_merge($params, $optParams);
+ return $this->call('updateImap', [$params], ImapSettings::class);
+ }
+ /**
+ * Updates language settings. If successful, the return object contains the
+ * `displayLanguage` that was saved for the user, which may differ from the
+ * value passed into the request. This is because the requested
+ * `displayLanguage` may not be directly supported by Gmail but have a close
+ * variant that is, and so the variant may be chosen and saved instead.
+ * (settings.updateLanguage)
+ *
+ * @param string $userId User's email address. The special value "me" can be
+ * used to indicate the authenticated user.
+ * @param LanguageSettings $postBody
+ * @param array $optParams Optional parameters.
+ * @return LanguageSettings
+ * @throws \Google\Service\Exception
+ */
+ public function updateLanguage($userId, LanguageSettings $postBody, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'postBody' => $postBody];
+ $params = \array_merge($params, $optParams);
+ return $this->call('updateLanguage', [$params], LanguageSettings::class);
+ }
+ /**
+ * Updates POP settings. (settings.updatePop)
+ *
+ * @param string $userId User's email address. The special value "me" can be
+ * used to indicate the authenticated user.
+ * @param PopSettings $postBody
+ * @param array $optParams Optional parameters.
+ * @return PopSettings
+ * @throws \Google\Service\Exception
+ */
+ public function updatePop($userId, PopSettings $postBody, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'postBody' => $postBody];
+ $params = \array_merge($params, $optParams);
+ return $this->call('updatePop', [$params], PopSettings::class);
+ }
+ /**
+ * Updates vacation responder settings. (settings.updateVacation)
+ *
+ * @param string $userId User's email address. The special value "me" can be
+ * used to indicate the authenticated user.
+ * @param VacationSettings $postBody
+ * @param array $optParams Optional parameters.
+ * @return VacationSettings
+ * @throws \Google\Service\Exception
+ */
+ public function updateVacation($userId, VacationSettings $postBody, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'postBody' => $postBody];
+ $params = \array_merge($params, $optParams);
+ return $this->call('updateVacation', [$params], VacationSettings::class);
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(UsersSettings::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_Resource_UsersSettings');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/UsersSettingsCse.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/UsersSettingsCse.php
new file mode 100755
index 00000000..017afd22
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/UsersSettingsCse.php
@@ -0,0 +1,32 @@
+
+ * $gmailService = new Google\Service\Gmail(...);
+ * $cse = $gmailService->users_settings_cse;
+ *
+ */
+class UsersSettingsCse extends \WPMailSMTP\Vendor\Google\Service\Resource
+{
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(UsersSettingsCse::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_Resource_UsersSettingsCse');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/UsersSettingsCseIdentities.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/UsersSettingsCseIdentities.php
new file mode 100755
index 00000000..34314f62
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/UsersSettingsCseIdentities.php
@@ -0,0 +1,132 @@
+
+ * $gmailService = new Google\Service\Gmail(...);
+ * $identities = $gmailService->users_settings_cse_identities;
+ *
+ */
+class UsersSettingsCseIdentities extends \WPMailSMTP\Vendor\Google\Service\Resource
+{
+ /**
+ * Creates and configures a client-side encryption identity that's authorized to
+ * send mail from the user account. Google publishes the S/MIME certificate to a
+ * shared domain-wide directory so that people within a Google Workspace
+ * organization can encrypt and send mail to the identity. (identities.create)
+ *
+ * @param string $userId The requester's primary email address. To indicate the
+ * authenticated user, you can use the special value `me`.
+ * @param CseIdentity $postBody
+ * @param array $optParams Optional parameters.
+ * @return CseIdentity
+ * @throws \Google\Service\Exception
+ */
+ public function create($userId, CseIdentity $postBody, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'postBody' => $postBody];
+ $params = \array_merge($params, $optParams);
+ return $this->call('create', [$params], CseIdentity::class);
+ }
+ /**
+ * Deletes a client-side encryption identity. The authenticated user can no
+ * longer use the identity to send encrypted messages. You cannot restore the
+ * identity after you delete it. Instead, use the CreateCseIdentity method to
+ * create another identity with the same configuration. (identities.delete)
+ *
+ * @param string $userId The requester's primary email address. To indicate the
+ * authenticated user, you can use the special value `me`.
+ * @param string $cseEmailAddress The primary email address associated with the
+ * client-side encryption identity configuration that's removed.
+ * @param array $optParams Optional parameters.
+ * @throws \Google\Service\Exception
+ */
+ public function delete($userId, $cseEmailAddress, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'cseEmailAddress' => $cseEmailAddress];
+ $params = \array_merge($params, $optParams);
+ return $this->call('delete', [$params]);
+ }
+ /**
+ * Retrieves a client-side encryption identity configuration. (identities.get)
+ *
+ * @param string $userId The requester's primary email address. To indicate the
+ * authenticated user, you can use the special value `me`.
+ * @param string $cseEmailAddress The primary email address associated with the
+ * client-side encryption identity configuration that's retrieved.
+ * @param array $optParams Optional parameters.
+ * @return CseIdentity
+ * @throws \Google\Service\Exception
+ */
+ public function get($userId, $cseEmailAddress, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'cseEmailAddress' => $cseEmailAddress];
+ $params = \array_merge($params, $optParams);
+ return $this->call('get', [$params], CseIdentity::class);
+ }
+ /**
+ * Lists the client-side encrypted identities for an authenticated user.
+ * (identities.listUsersSettingsCseIdentities)
+ *
+ * @param string $userId The requester's primary email address. To indicate the
+ * authenticated user, you can use the special value `me`.
+ * @param array $optParams Optional parameters.
+ *
+ * @opt_param int pageSize The number of identities to return. If not provided,
+ * the page size will default to 20 entries.
+ * @opt_param string pageToken Pagination token indicating which page of
+ * identities to return. If the token is not supplied, then the API will return
+ * the first page of results.
+ * @return ListCseIdentitiesResponse
+ * @throws \Google\Service\Exception
+ */
+ public function listUsersSettingsCseIdentities($userId, $optParams = [])
+ {
+ $params = ['userId' => $userId];
+ $params = \array_merge($params, $optParams);
+ return $this->call('list', [$params], ListCseIdentitiesResponse::class);
+ }
+ /**
+ * Associates a different key pair with an existing client-side encryption
+ * identity. The updated key pair must validate against Google's [S/MIME
+ * certificate profiles](https://support.google.com/a/answer/7300887).
+ * (identities.patch)
+ *
+ * @param string $userId The requester's primary email address. To indicate the
+ * authenticated user, you can use the special value `me`.
+ * @param string $emailAddress The email address of the client-side encryption
+ * identity to update.
+ * @param CseIdentity $postBody
+ * @param array $optParams Optional parameters.
+ * @return CseIdentity
+ * @throws \Google\Service\Exception
+ */
+ public function patch($userId, $emailAddress, CseIdentity $postBody, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'emailAddress' => $emailAddress, 'postBody' => $postBody];
+ $params = \array_merge($params, $optParams);
+ return $this->call('patch', [$params], CseIdentity::class);
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(UsersSettingsCseIdentities::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_Resource_UsersSettingsCseIdentities');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/UsersSettingsCseKeypairs.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/UsersSettingsCseKeypairs.php
new file mode 100755
index 00000000..5dababee
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/UsersSettingsCseKeypairs.php
@@ -0,0 +1,153 @@
+
+ * $gmailService = new Google\Service\Gmail(...);
+ * $keypairs = $gmailService->users_settings_cse_keypairs;
+ *
+ */
+class UsersSettingsCseKeypairs extends \WPMailSMTP\Vendor\Google\Service\Resource
+{
+ /**
+ * Creates and uploads a client-side encryption S/MIME public key certificate
+ * chain and private key metadata for the authenticated user. (keypairs.create)
+ *
+ * @param string $userId The requester's primary email address. To indicate the
+ * authenticated user, you can use the special value `me`.
+ * @param CseKeyPair $postBody
+ * @param array $optParams Optional parameters.
+ * @return CseKeyPair
+ * @throws \Google\Service\Exception
+ */
+ public function create($userId, CseKeyPair $postBody, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'postBody' => $postBody];
+ $params = \array_merge($params, $optParams);
+ return $this->call('create', [$params], CseKeyPair::class);
+ }
+ /**
+ * Turns off a client-side encryption key pair. The authenticated user can no
+ * longer use the key pair to decrypt incoming CSE message texts or sign
+ * outgoing CSE mail. To regain access, use the EnableCseKeyPair to turn on the
+ * key pair. After 30 days, you can permanently delete the key pair by using the
+ * ObliterateCseKeyPair method. (keypairs.disable)
+ *
+ * @param string $userId The requester's primary email address. To indicate the
+ * authenticated user, you can use the special value `me`.
+ * @param string $keyPairId The identifier of the key pair to turn off.
+ * @param DisableCseKeyPairRequest $postBody
+ * @param array $optParams Optional parameters.
+ * @return CseKeyPair
+ * @throws \Google\Service\Exception
+ */
+ public function disable($userId, $keyPairId, DisableCseKeyPairRequest $postBody, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'keyPairId' => $keyPairId, 'postBody' => $postBody];
+ $params = \array_merge($params, $optParams);
+ return $this->call('disable', [$params], CseKeyPair::class);
+ }
+ /**
+ * Turns on a client-side encryption key pair that was turned off. The key pair
+ * becomes active again for any associated client-side encryption identities.
+ * (keypairs.enable)
+ *
+ * @param string $userId The requester's primary email address. To indicate the
+ * authenticated user, you can use the special value `me`.
+ * @param string $keyPairId The identifier of the key pair to turn on.
+ * @param EnableCseKeyPairRequest $postBody
+ * @param array $optParams Optional parameters.
+ * @return CseKeyPair
+ * @throws \Google\Service\Exception
+ */
+ public function enable($userId, $keyPairId, EnableCseKeyPairRequest $postBody, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'keyPairId' => $keyPairId, 'postBody' => $postBody];
+ $params = \array_merge($params, $optParams);
+ return $this->call('enable', [$params], CseKeyPair::class);
+ }
+ /**
+ * Retrieves an existing client-side encryption key pair. (keypairs.get)
+ *
+ * @param string $userId The requester's primary email address. To indicate the
+ * authenticated user, you can use the special value `me`.
+ * @param string $keyPairId The identifier of the key pair to retrieve.
+ * @param array $optParams Optional parameters.
+ * @return CseKeyPair
+ * @throws \Google\Service\Exception
+ */
+ public function get($userId, $keyPairId, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'keyPairId' => $keyPairId];
+ $params = \array_merge($params, $optParams);
+ return $this->call('get', [$params], CseKeyPair::class);
+ }
+ /**
+ * Lists client-side encryption key pairs for an authenticated user.
+ * (keypairs.listUsersSettingsCseKeypairs)
+ *
+ * @param string $userId The requester's primary email address. To indicate the
+ * authenticated user, you can use the special value `me`.
+ * @param array $optParams Optional parameters.
+ *
+ * @opt_param int pageSize The number of key pairs to return. If not provided,
+ * the page size will default to 20 entries.
+ * @opt_param string pageToken Pagination token indicating which page of key
+ * pairs to return. If the token is not supplied, then the API will return the
+ * first page of results.
+ * @return ListCseKeyPairsResponse
+ * @throws \Google\Service\Exception
+ */
+ public function listUsersSettingsCseKeypairs($userId, $optParams = [])
+ {
+ $params = ['userId' => $userId];
+ $params = \array_merge($params, $optParams);
+ return $this->call('list', [$params], ListCseKeyPairsResponse::class);
+ }
+ /**
+ * Deletes a client-side encryption key pair permanently and immediately. You
+ * can only permanently delete key pairs that have been turned off for more than
+ * 30 days. To turn off a key pair, use the DisableCseKeyPair method. Gmail
+ * can't restore or decrypt any messages that were encrypted by an obliterated
+ * key. Authenticated users and Google Workspace administrators lose access to
+ * reading the encrypted messages. (keypairs.obliterate)
+ *
+ * @param string $userId The requester's primary email address. To indicate the
+ * authenticated user, you can use the special value `me`.
+ * @param string $keyPairId The identifier of the key pair to obliterate.
+ * @param ObliterateCseKeyPairRequest $postBody
+ * @param array $optParams Optional parameters.
+ * @throws \Google\Service\Exception
+ */
+ public function obliterate($userId, $keyPairId, ObliterateCseKeyPairRequest $postBody, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'keyPairId' => $keyPairId, 'postBody' => $postBody];
+ $params = \array_merge($params, $optParams);
+ return $this->call('obliterate', [$params]);
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(UsersSettingsCseKeypairs::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_Resource_UsersSettingsCseKeypairs');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/UsersSettingsDelegates.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/UsersSettingsDelegates.php
new file mode 100755
index 00000000..9bc2426d
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/UsersSettingsDelegates.php
@@ -0,0 +1,117 @@
+
+ * $gmailService = new Google\Service\Gmail(...);
+ * $delegates = $gmailService->users_settings_delegates;
+ *
+ */
+class UsersSettingsDelegates extends \WPMailSMTP\Vendor\Google\Service\Resource
+{
+ /**
+ * Adds a delegate with its verification status set directly to `accepted`,
+ * without sending any verification email. The delegate user must be a member of
+ * the same Google Workspace organization as the delegator user. Gmail imposes
+ * limitations on the number of delegates and delegators each user in a Google
+ * Workspace organization can have. These limits depend on your organization,
+ * but in general each user can have up to 25 delegates and up to 10 delegators.
+ * Note that a delegate user must be referred to by their primary email address,
+ * and not an email alias. Also note that when a new delegate is created, there
+ * may be up to a one minute delay before the new delegate is available for use.
+ * This method is only available to service account clients that have been
+ * delegated domain-wide authority. (delegates.create)
+ *
+ * @param string $userId User's email address. The special value "me" can be
+ * used to indicate the authenticated user.
+ * @param Delegate $postBody
+ * @param array $optParams Optional parameters.
+ * @return Delegate
+ * @throws \Google\Service\Exception
+ */
+ public function create($userId, Delegate $postBody, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'postBody' => $postBody];
+ $params = \array_merge($params, $optParams);
+ return $this->call('create', [$params], Delegate::class);
+ }
+ /**
+ * Removes the specified delegate (which can be of any verification status), and
+ * revokes any verification that may have been required for using it. Note that
+ * a delegate user must be referred to by their primary email address, and not
+ * an email alias. This method is only available to service account clients that
+ * have been delegated domain-wide authority. (delegates.delete)
+ *
+ * @param string $userId User's email address. The special value "me" can be
+ * used to indicate the authenticated user.
+ * @param string $delegateEmail The email address of the user to be removed as a
+ * delegate.
+ * @param array $optParams Optional parameters.
+ * @throws \Google\Service\Exception
+ */
+ public function delete($userId, $delegateEmail, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'delegateEmail' => $delegateEmail];
+ $params = \array_merge($params, $optParams);
+ return $this->call('delete', [$params]);
+ }
+ /**
+ * Gets the specified delegate. Note that a delegate user must be referred to by
+ * their primary email address, and not an email alias. This method is only
+ * available to service account clients that have been delegated domain-wide
+ * authority. (delegates.get)
+ *
+ * @param string $userId User's email address. The special value "me" can be
+ * used to indicate the authenticated user.
+ * @param string $delegateEmail The email address of the user whose delegate
+ * relationship is to be retrieved.
+ * @param array $optParams Optional parameters.
+ * @return Delegate
+ * @throws \Google\Service\Exception
+ */
+ public function get($userId, $delegateEmail, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'delegateEmail' => $delegateEmail];
+ $params = \array_merge($params, $optParams);
+ return $this->call('get', [$params], Delegate::class);
+ }
+ /**
+ * Lists the delegates for the specified account. This method is only available
+ * to service account clients that have been delegated domain-wide authority.
+ * (delegates.listUsersSettingsDelegates)
+ *
+ * @param string $userId User's email address. The special value "me" can be
+ * used to indicate the authenticated user.
+ * @param array $optParams Optional parameters.
+ * @return ListDelegatesResponse
+ * @throws \Google\Service\Exception
+ */
+ public function listUsersSettingsDelegates($userId, $optParams = [])
+ {
+ $params = ['userId' => $userId];
+ $params = \array_merge($params, $optParams);
+ return $this->call('list', [$params], ListDelegatesResponse::class);
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(UsersSettingsDelegates::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_Resource_UsersSettingsDelegates');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/UsersSettingsFilters.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/UsersSettingsFilters.php
new file mode 100755
index 00000000..fd642e0d
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/UsersSettingsFilters.php
@@ -0,0 +1,97 @@
+
+ * $gmailService = new Google\Service\Gmail(...);
+ * $filters = $gmailService->users_settings_filters;
+ *
+ */
+class UsersSettingsFilters extends \WPMailSMTP\Vendor\Google\Service\Resource
+{
+ /**
+ * Creates a filter. Note: you can only create a maximum of 1,000 filters.
+ * (filters.create)
+ *
+ * @param string $userId User's email address. The special value "me" can be
+ * used to indicate the authenticated user.
+ * @param Filter $postBody
+ * @param array $optParams Optional parameters.
+ * @return Filter
+ * @throws \Google\Service\Exception
+ */
+ public function create($userId, Filter $postBody, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'postBody' => $postBody];
+ $params = \array_merge($params, $optParams);
+ return $this->call('create', [$params], Filter::class);
+ }
+ /**
+ * Immediately and permanently deletes the specified filter. (filters.delete)
+ *
+ * @param string $userId User's email address. The special value "me" can be
+ * used to indicate the authenticated user.
+ * @param string $id The ID of the filter to be deleted.
+ * @param array $optParams Optional parameters.
+ * @throws \Google\Service\Exception
+ */
+ public function delete($userId, $id, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'id' => $id];
+ $params = \array_merge($params, $optParams);
+ return $this->call('delete', [$params]);
+ }
+ /**
+ * Gets a filter. (filters.get)
+ *
+ * @param string $userId User's email address. The special value "me" can be
+ * used to indicate the authenticated user.
+ * @param string $id The ID of the filter to be fetched.
+ * @param array $optParams Optional parameters.
+ * @return Filter
+ * @throws \Google\Service\Exception
+ */
+ public function get($userId, $id, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'id' => $id];
+ $params = \array_merge($params, $optParams);
+ return $this->call('get', [$params], Filter::class);
+ }
+ /**
+ * Lists the message filters of a Gmail user. (filters.listUsersSettingsFilters)
+ *
+ * @param string $userId User's email address. The special value "me" can be
+ * used to indicate the authenticated user.
+ * @param array $optParams Optional parameters.
+ * @return ListFiltersResponse
+ * @throws \Google\Service\Exception
+ */
+ public function listUsersSettingsFilters($userId, $optParams = [])
+ {
+ $params = ['userId' => $userId];
+ $params = \array_merge($params, $optParams);
+ return $this->call('list', [$params], ListFiltersResponse::class);
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(UsersSettingsFilters::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_Resource_UsersSettingsFilters');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/UsersSettingsForwardingAddresses.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/UsersSettingsForwardingAddresses.php
new file mode 100755
index 00000000..46b506d0
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/UsersSettingsForwardingAddresses.php
@@ -0,0 +1,105 @@
+
+ * $gmailService = new Google\Service\Gmail(...);
+ * $forwardingAddresses = $gmailService->users_settings_forwardingAddresses;
+ *
+ */
+class UsersSettingsForwardingAddresses extends \WPMailSMTP\Vendor\Google\Service\Resource
+{
+ /**
+ * Creates a forwarding address. If ownership verification is required, a
+ * message will be sent to the recipient and the resource's verification status
+ * will be set to `pending`; otherwise, the resource will be created with
+ * verification status set to `accepted`. This method is only available to
+ * service account clients that have been delegated domain-wide authority.
+ * (forwardingAddresses.create)
+ *
+ * @param string $userId User's email address. The special value "me" can be
+ * used to indicate the authenticated user.
+ * @param ForwardingAddress $postBody
+ * @param array $optParams Optional parameters.
+ * @return ForwardingAddress
+ * @throws \Google\Service\Exception
+ */
+ public function create($userId, ForwardingAddress $postBody, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'postBody' => $postBody];
+ $params = \array_merge($params, $optParams);
+ return $this->call('create', [$params], ForwardingAddress::class);
+ }
+ /**
+ * Deletes the specified forwarding address and revokes any verification that
+ * may have been required. This method is only available to service account
+ * clients that have been delegated domain-wide authority.
+ * (forwardingAddresses.delete)
+ *
+ * @param string $userId User's email address. The special value "me" can be
+ * used to indicate the authenticated user.
+ * @param string $forwardingEmail The forwarding address to be deleted.
+ * @param array $optParams Optional parameters.
+ * @throws \Google\Service\Exception
+ */
+ public function delete($userId, $forwardingEmail, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'forwardingEmail' => $forwardingEmail];
+ $params = \array_merge($params, $optParams);
+ return $this->call('delete', [$params]);
+ }
+ /**
+ * Gets the specified forwarding address. (forwardingAddresses.get)
+ *
+ * @param string $userId User's email address. The special value "me" can be
+ * used to indicate the authenticated user.
+ * @param string $forwardingEmail The forwarding address to be retrieved.
+ * @param array $optParams Optional parameters.
+ * @return ForwardingAddress
+ * @throws \Google\Service\Exception
+ */
+ public function get($userId, $forwardingEmail, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'forwardingEmail' => $forwardingEmail];
+ $params = \array_merge($params, $optParams);
+ return $this->call('get', [$params], ForwardingAddress::class);
+ }
+ /**
+ * Lists the forwarding addresses for the specified account.
+ * (forwardingAddresses.listUsersSettingsForwardingAddresses)
+ *
+ * @param string $userId User's email address. The special value "me" can be
+ * used to indicate the authenticated user.
+ * @param array $optParams Optional parameters.
+ * @return ListForwardingAddressesResponse
+ * @throws \Google\Service\Exception
+ */
+ public function listUsersSettingsForwardingAddresses($userId, $optParams = [])
+ {
+ $params = ['userId' => $userId];
+ $params = \array_merge($params, $optParams);
+ return $this->call('list', [$params], ListForwardingAddressesResponse::class);
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(UsersSettingsForwardingAddresses::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_Resource_UsersSettingsForwardingAddresses');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/UsersSettingsSendAs.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/UsersSettingsSendAs.php
new file mode 100755
index 00000000..801c79a9
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/UsersSettingsSendAs.php
@@ -0,0 +1,164 @@
+
+ * $gmailService = new Google\Service\Gmail(...);
+ * $sendAs = $gmailService->users_settings_sendAs;
+ *
+ */
+class UsersSettingsSendAs extends \WPMailSMTP\Vendor\Google\Service\Resource
+{
+ /**
+ * Creates a custom "from" send-as alias. If an SMTP MSA is specified, Gmail
+ * will attempt to connect to the SMTP service to validate the configuration
+ * before creating the alias. If ownership verification is required for the
+ * alias, a message will be sent to the email address and the resource's
+ * verification status will be set to `pending`; otherwise, the resource will be
+ * created with verification status set to `accepted`. If a signature is
+ * provided, Gmail will sanitize the HTML before saving it with the alias. This
+ * method is only available to service account clients that have been delegated
+ * domain-wide authority. (sendAs.create)
+ *
+ * @param string $userId User's email address. The special value "me" can be
+ * used to indicate the authenticated user.
+ * @param SendAs $postBody
+ * @param array $optParams Optional parameters.
+ * @return SendAs
+ * @throws \Google\Service\Exception
+ */
+ public function create($userId, SendAs $postBody, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'postBody' => $postBody];
+ $params = \array_merge($params, $optParams);
+ return $this->call('create', [$params], SendAs::class);
+ }
+ /**
+ * Deletes the specified send-as alias. Revokes any verification that may have
+ * been required for using it. This method is only available to service account
+ * clients that have been delegated domain-wide authority. (sendAs.delete)
+ *
+ * @param string $userId User's email address. The special value "me" can be
+ * used to indicate the authenticated user.
+ * @param string $sendAsEmail The send-as alias to be deleted.
+ * @param array $optParams Optional parameters.
+ * @throws \Google\Service\Exception
+ */
+ public function delete($userId, $sendAsEmail, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'sendAsEmail' => $sendAsEmail];
+ $params = \array_merge($params, $optParams);
+ return $this->call('delete', [$params]);
+ }
+ /**
+ * Gets the specified send-as alias. Fails with an HTTP 404 error if the
+ * specified address is not a member of the collection. (sendAs.get)
+ *
+ * @param string $userId User's email address. The special value "me" can be
+ * used to indicate the authenticated user.
+ * @param string $sendAsEmail The send-as alias to be retrieved.
+ * @param array $optParams Optional parameters.
+ * @return SendAs
+ * @throws \Google\Service\Exception
+ */
+ public function get($userId, $sendAsEmail, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'sendAsEmail' => $sendAsEmail];
+ $params = \array_merge($params, $optParams);
+ return $this->call('get', [$params], SendAs::class);
+ }
+ /**
+ * Lists the send-as aliases for the specified account. The result includes the
+ * primary send-as address associated with the account as well as any custom
+ * "from" aliases. (sendAs.listUsersSettingsSendAs)
+ *
+ * @param string $userId User's email address. The special value "me" can be
+ * used to indicate the authenticated user.
+ * @param array $optParams Optional parameters.
+ * @return ListSendAsResponse
+ * @throws \Google\Service\Exception
+ */
+ public function listUsersSettingsSendAs($userId, $optParams = [])
+ {
+ $params = ['userId' => $userId];
+ $params = \array_merge($params, $optParams);
+ return $this->call('list', [$params], ListSendAsResponse::class);
+ }
+ /**
+ * Patch the specified send-as alias. (sendAs.patch)
+ *
+ * @param string $userId User's email address. The special value "me" can be
+ * used to indicate the authenticated user.
+ * @param string $sendAsEmail The send-as alias to be updated.
+ * @param SendAs $postBody
+ * @param array $optParams Optional parameters.
+ * @return SendAs
+ * @throws \Google\Service\Exception
+ */
+ public function patch($userId, $sendAsEmail, SendAs $postBody, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'sendAsEmail' => $sendAsEmail, 'postBody' => $postBody];
+ $params = \array_merge($params, $optParams);
+ return $this->call('patch', [$params], SendAs::class);
+ }
+ /**
+ * Updates a send-as alias. If a signature is provided, Gmail will sanitize the
+ * HTML before saving it with the alias. Addresses other than the primary
+ * address for the account can only be updated by service account clients that
+ * have been delegated domain-wide authority. (sendAs.update)
+ *
+ * @param string $userId User's email address. The special value "me" can be
+ * used to indicate the authenticated user.
+ * @param string $sendAsEmail The send-as alias to be updated.
+ * @param SendAs $postBody
+ * @param array $optParams Optional parameters.
+ * @return SendAs
+ * @throws \Google\Service\Exception
+ */
+ public function update($userId, $sendAsEmail, SendAs $postBody, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'sendAsEmail' => $sendAsEmail, 'postBody' => $postBody];
+ $params = \array_merge($params, $optParams);
+ return $this->call('update', [$params], SendAs::class);
+ }
+ /**
+ * Sends a verification email to the specified send-as alias address. The
+ * verification status must be `pending`. This method is only available to
+ * service account clients that have been delegated domain-wide authority.
+ * (sendAs.verify)
+ *
+ * @param string $userId User's email address. The special value "me" can be
+ * used to indicate the authenticated user.
+ * @param string $sendAsEmail The send-as alias to be verified.
+ * @param array $optParams Optional parameters.
+ * @throws \Google\Service\Exception
+ */
+ public function verify($userId, $sendAsEmail, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'sendAsEmail' => $sendAsEmail];
+ $params = \array_merge($params, $optParams);
+ return $this->call('verify', [$params]);
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(UsersSettingsSendAs::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_Resource_UsersSettingsSendAs');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/UsersSettingsSendAsSmimeInfo.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/UsersSettingsSendAsSmimeInfo.php
new file mode 100755
index 00000000..c0e9d7c7
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/UsersSettingsSendAsSmimeInfo.php
@@ -0,0 +1,126 @@
+
+ * $gmailService = new Google\Service\Gmail(...);
+ * $smimeInfo = $gmailService->users_settings_sendAs_smimeInfo;
+ *
+ */
+class UsersSettingsSendAsSmimeInfo extends \WPMailSMTP\Vendor\Google\Service\Resource
+{
+ /**
+ * Deletes the specified S/MIME config for the specified send-as alias.
+ * (smimeInfo.delete)
+ *
+ * @param string $userId The user's email address. The special value `me` can be
+ * used to indicate the authenticated user.
+ * @param string $sendAsEmail The email address that appears in the "From:"
+ * header for mail sent using this alias.
+ * @param string $id The immutable ID for the SmimeInfo.
+ * @param array $optParams Optional parameters.
+ * @throws \Google\Service\Exception
+ */
+ public function delete($userId, $sendAsEmail, $id, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'sendAsEmail' => $sendAsEmail, 'id' => $id];
+ $params = \array_merge($params, $optParams);
+ return $this->call('delete', [$params]);
+ }
+ /**
+ * Gets the specified S/MIME config for the specified send-as alias.
+ * (smimeInfo.get)
+ *
+ * @param string $userId The user's email address. The special value `me` can be
+ * used to indicate the authenticated user.
+ * @param string $sendAsEmail The email address that appears in the "From:"
+ * header for mail sent using this alias.
+ * @param string $id The immutable ID for the SmimeInfo.
+ * @param array $optParams Optional parameters.
+ * @return SmimeInfo
+ * @throws \Google\Service\Exception
+ */
+ public function get($userId, $sendAsEmail, $id, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'sendAsEmail' => $sendAsEmail, 'id' => $id];
+ $params = \array_merge($params, $optParams);
+ return $this->call('get', [$params], SmimeInfo::class);
+ }
+ /**
+ * Insert (upload) the given S/MIME config for the specified send-as alias. Note
+ * that pkcs12 format is required for the key. (smimeInfo.insert)
+ *
+ * @param string $userId The user's email address. The special value `me` can be
+ * used to indicate the authenticated user.
+ * @param string $sendAsEmail The email address that appears in the "From:"
+ * header for mail sent using this alias.
+ * @param SmimeInfo $postBody
+ * @param array $optParams Optional parameters.
+ * @return SmimeInfo
+ * @throws \Google\Service\Exception
+ */
+ public function insert($userId, $sendAsEmail, SmimeInfo $postBody, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'sendAsEmail' => $sendAsEmail, 'postBody' => $postBody];
+ $params = \array_merge($params, $optParams);
+ return $this->call('insert', [$params], SmimeInfo::class);
+ }
+ /**
+ * Lists S/MIME configs for the specified send-as alias.
+ * (smimeInfo.listUsersSettingsSendAsSmimeInfo)
+ *
+ * @param string $userId The user's email address. The special value `me` can be
+ * used to indicate the authenticated user.
+ * @param string $sendAsEmail The email address that appears in the "From:"
+ * header for mail sent using this alias.
+ * @param array $optParams Optional parameters.
+ * @return ListSmimeInfoResponse
+ * @throws \Google\Service\Exception
+ */
+ public function listUsersSettingsSendAsSmimeInfo($userId, $sendAsEmail, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'sendAsEmail' => $sendAsEmail];
+ $params = \array_merge($params, $optParams);
+ return $this->call('list', [$params], ListSmimeInfoResponse::class);
+ }
+ /**
+ * Sets the default S/MIME config for the specified send-as alias.
+ * (smimeInfo.setDefault)
+ *
+ * @param string $userId The user's email address. The special value `me` can be
+ * used to indicate the authenticated user.
+ * @param string $sendAsEmail The email address that appears in the "From:"
+ * header for mail sent using this alias.
+ * @param string $id The immutable ID for the SmimeInfo.
+ * @param array $optParams Optional parameters.
+ * @throws \Google\Service\Exception
+ */
+ public function setDefault($userId, $sendAsEmail, $id, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'sendAsEmail' => $sendAsEmail, 'id' => $id];
+ $params = \array_merge($params, $optParams);
+ return $this->call('setDefault', [$params]);
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(UsersSettingsSendAsSmimeInfo::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_Resource_UsersSettingsSendAsSmimeInfo');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/UsersThreads.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/UsersThreads.php
new file mode 100755
index 00000000..52a3bba0
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Resource/UsersThreads.php
@@ -0,0 +1,154 @@
+
+ * $gmailService = new Google\Service\Gmail(...);
+ * $threads = $gmailService->users_threads;
+ *
+ */
+class UsersThreads extends \WPMailSMTP\Vendor\Google\Service\Resource
+{
+ /**
+ * Immediately and permanently deletes the specified thread. Any messages that
+ * belong to the thread are also deleted. This operation cannot be undone.
+ * Prefer `threads.trash` instead. (threads.delete)
+ *
+ * @param string $userId The user's email address. The special value `me` can be
+ * used to indicate the authenticated user.
+ * @param string $id ID of the Thread to delete.
+ * @param array $optParams Optional parameters.
+ * @throws \Google\Service\Exception
+ */
+ public function delete($userId, $id, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'id' => $id];
+ $params = \array_merge($params, $optParams);
+ return $this->call('delete', [$params]);
+ }
+ /**
+ * Gets the specified thread. (threads.get)
+ *
+ * @param string $userId The user's email address. The special value `me` can be
+ * used to indicate the authenticated user.
+ * @param string $id The ID of the thread to retrieve.
+ * @param array $optParams Optional parameters.
+ *
+ * @opt_param string format The format to return the messages in.
+ * @opt_param string metadataHeaders When given and format is METADATA, only
+ * include headers specified.
+ * @opt_param bool temporaryEeccBypass
+ * @return Thread
+ * @throws \Google\Service\Exception
+ */
+ public function get($userId, $id, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'id' => $id];
+ $params = \array_merge($params, $optParams);
+ return $this->call('get', [$params], Thread::class);
+ }
+ /**
+ * Lists the threads in the user's mailbox. (threads.listUsersThreads)
+ *
+ * @param string $userId The user's email address. The special value `me` can be
+ * used to indicate the authenticated user.
+ * @param array $optParams Optional parameters.
+ *
+ * @opt_param bool includeSpamTrash Include threads from `SPAM` and `TRASH` in
+ * the results.
+ * @opt_param string labelIds Only return threads with labels that match all of
+ * the specified label IDs.
+ * @opt_param string maxResults Maximum number of threads to return. This field
+ * defaults to 100. The maximum allowed value for this field is 500.
+ * @opt_param string pageToken Page token to retrieve a specific page of results
+ * in the list.
+ * @opt_param string q Only return threads matching the specified query.
+ * Supports the same query format as the Gmail search box. For example,
+ * `"from:someuser@example.com rfc822msgid: is:unread"`. Parameter cannot be
+ * used when accessing the api using the gmail.metadata scope.
+ * @opt_param bool temporaryEeccBypass
+ * @return ListThreadsResponse
+ * @throws \Google\Service\Exception
+ */
+ public function listUsersThreads($userId, $optParams = [])
+ {
+ $params = ['userId' => $userId];
+ $params = \array_merge($params, $optParams);
+ return $this->call('list', [$params], ListThreadsResponse::class);
+ }
+ /**
+ * Modifies the labels applied to the thread. This applies to all messages in
+ * the thread. (threads.modify)
+ *
+ * @param string $userId The user's email address. The special value `me` can be
+ * used to indicate the authenticated user.
+ * @param string $id The ID of the thread to modify.
+ * @param ModifyThreadRequest $postBody
+ * @param array $optParams Optional parameters.
+ * @return Thread
+ * @throws \Google\Service\Exception
+ */
+ public function modify($userId, $id, ModifyThreadRequest $postBody, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'id' => $id, 'postBody' => $postBody];
+ $params = \array_merge($params, $optParams);
+ return $this->call('modify', [$params], Thread::class);
+ }
+ /**
+ * Moves the specified thread to the trash. Any messages that belong to the
+ * thread are also moved to the trash. (threads.trash)
+ *
+ * @param string $userId The user's email address. The special value `me` can be
+ * used to indicate the authenticated user.
+ * @param string $id The ID of the thread to Trash.
+ * @param array $optParams Optional parameters.
+ * @return Thread
+ * @throws \Google\Service\Exception
+ */
+ public function trash($userId, $id, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'id' => $id];
+ $params = \array_merge($params, $optParams);
+ return $this->call('trash', [$params], Thread::class);
+ }
+ /**
+ * Removes the specified thread from the trash. Any messages that belong to the
+ * thread are also removed from the trash. (threads.untrash)
+ *
+ * @param string $userId The user's email address. The special value `me` can be
+ * used to indicate the authenticated user.
+ * @param string $id The ID of the thread to remove from Trash.
+ * @param array $optParams Optional parameters.
+ * @return Thread
+ * @throws \Google\Service\Exception
+ */
+ public function untrash($userId, $id, $optParams = [])
+ {
+ $params = ['userId' => $userId, 'id' => $id];
+ $params = \array_merge($params, $optParams);
+ return $this->call('untrash', [$params], Thread::class);
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(UsersThreads::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_Resource_UsersThreads');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/SendAs.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/SendAs.php
new file mode 100755
index 00000000..e3fa4f6c
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/SendAs.php
@@ -0,0 +1,184 @@
+displayName = $displayName;
+ }
+ /**
+ * @return string
+ */
+ public function getDisplayName()
+ {
+ return $this->displayName;
+ }
+ /**
+ * @param bool
+ */
+ public function setIsDefault($isDefault)
+ {
+ $this->isDefault = $isDefault;
+ }
+ /**
+ * @return bool
+ */
+ public function getIsDefault()
+ {
+ return $this->isDefault;
+ }
+ /**
+ * @param bool
+ */
+ public function setIsPrimary($isPrimary)
+ {
+ $this->isPrimary = $isPrimary;
+ }
+ /**
+ * @return bool
+ */
+ public function getIsPrimary()
+ {
+ return $this->isPrimary;
+ }
+ /**
+ * @param string
+ */
+ public function setReplyToAddress($replyToAddress)
+ {
+ $this->replyToAddress = $replyToAddress;
+ }
+ /**
+ * @return string
+ */
+ public function getReplyToAddress()
+ {
+ return $this->replyToAddress;
+ }
+ /**
+ * @param string
+ */
+ public function setSendAsEmail($sendAsEmail)
+ {
+ $this->sendAsEmail = $sendAsEmail;
+ }
+ /**
+ * @return string
+ */
+ public function getSendAsEmail()
+ {
+ return $this->sendAsEmail;
+ }
+ /**
+ * @param string
+ */
+ public function setSignature($signature)
+ {
+ $this->signature = $signature;
+ }
+ /**
+ * @return string
+ */
+ public function getSignature()
+ {
+ return $this->signature;
+ }
+ /**
+ * @param SmtpMsa
+ */
+ public function setSmtpMsa(SmtpMsa $smtpMsa)
+ {
+ $this->smtpMsa = $smtpMsa;
+ }
+ /**
+ * @return SmtpMsa
+ */
+ public function getSmtpMsa()
+ {
+ return $this->smtpMsa;
+ }
+ /**
+ * @param bool
+ */
+ public function setTreatAsAlias($treatAsAlias)
+ {
+ $this->treatAsAlias = $treatAsAlias;
+ }
+ /**
+ * @return bool
+ */
+ public function getTreatAsAlias()
+ {
+ return $this->treatAsAlias;
+ }
+ /**
+ * @param string
+ */
+ public function setVerificationStatus($verificationStatus)
+ {
+ $this->verificationStatus = $verificationStatus;
+ }
+ /**
+ * @return string
+ */
+ public function getVerificationStatus()
+ {
+ return $this->verificationStatus;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(SendAs::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_SendAs');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/SignAndEncryptKeyPairs.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/SignAndEncryptKeyPairs.php
new file mode 100755
index 00000000..2452e9f1
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/SignAndEncryptKeyPairs.php
@@ -0,0 +1,60 @@
+encryptionKeyPairId = $encryptionKeyPairId;
+ }
+ /**
+ * @return string
+ */
+ public function getEncryptionKeyPairId()
+ {
+ return $this->encryptionKeyPairId;
+ }
+ /**
+ * @param string
+ */
+ public function setSigningKeyPairId($signingKeyPairId)
+ {
+ $this->signingKeyPairId = $signingKeyPairId;
+ }
+ /**
+ * @return string
+ */
+ public function getSigningKeyPairId()
+ {
+ return $this->signingKeyPairId;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(SignAndEncryptKeyPairs::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_SignAndEncryptKeyPairs');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/SmimeInfo.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/SmimeInfo.php
new file mode 100755
index 00000000..0dc237b0
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/SmimeInfo.php
@@ -0,0 +1,150 @@
+encryptedKeyPassword = $encryptedKeyPassword;
+ }
+ /**
+ * @return string
+ */
+ public function getEncryptedKeyPassword()
+ {
+ return $this->encryptedKeyPassword;
+ }
+ /**
+ * @param string
+ */
+ public function setExpiration($expiration)
+ {
+ $this->expiration = $expiration;
+ }
+ /**
+ * @return string
+ */
+ public function getExpiration()
+ {
+ return $this->expiration;
+ }
+ /**
+ * @param string
+ */
+ public function setId($id)
+ {
+ $this->id = $id;
+ }
+ /**
+ * @return string
+ */
+ public function getId()
+ {
+ return $this->id;
+ }
+ /**
+ * @param bool
+ */
+ public function setIsDefault($isDefault)
+ {
+ $this->isDefault = $isDefault;
+ }
+ /**
+ * @return bool
+ */
+ public function getIsDefault()
+ {
+ return $this->isDefault;
+ }
+ /**
+ * @param string
+ */
+ public function setIssuerCn($issuerCn)
+ {
+ $this->issuerCn = $issuerCn;
+ }
+ /**
+ * @return string
+ */
+ public function getIssuerCn()
+ {
+ return $this->issuerCn;
+ }
+ /**
+ * @param string
+ */
+ public function setPem($pem)
+ {
+ $this->pem = $pem;
+ }
+ /**
+ * @return string
+ */
+ public function getPem()
+ {
+ return $this->pem;
+ }
+ /**
+ * @param string
+ */
+ public function setPkcs12($pkcs12)
+ {
+ $this->pkcs12 = $pkcs12;
+ }
+ /**
+ * @return string
+ */
+ public function getPkcs12()
+ {
+ return $this->pkcs12;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(SmimeInfo::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_SmimeInfo');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/SmtpMsa.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/SmtpMsa.php
new file mode 100755
index 00000000..a83e0f6c
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/SmtpMsa.php
@@ -0,0 +1,114 @@
+host = $host;
+ }
+ /**
+ * @return string
+ */
+ public function getHost()
+ {
+ return $this->host;
+ }
+ /**
+ * @param string
+ */
+ public function setPassword($password)
+ {
+ $this->password = $password;
+ }
+ /**
+ * @return string
+ */
+ public function getPassword()
+ {
+ return $this->password;
+ }
+ /**
+ * @param int
+ */
+ public function setPort($port)
+ {
+ $this->port = $port;
+ }
+ /**
+ * @return int
+ */
+ public function getPort()
+ {
+ return $this->port;
+ }
+ /**
+ * @param string
+ */
+ public function setSecurityMode($securityMode)
+ {
+ $this->securityMode = $securityMode;
+ }
+ /**
+ * @return string
+ */
+ public function getSecurityMode()
+ {
+ return $this->securityMode;
+ }
+ /**
+ * @param string
+ */
+ public function setUsername($username)
+ {
+ $this->username = $username;
+ }
+ /**
+ * @return string
+ */
+ public function getUsername()
+ {
+ return $this->username;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(SmtpMsa::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_SmtpMsa');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Thread.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Thread.php
new file mode 100755
index 00000000..30f020a1
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/Thread.php
@@ -0,0 +1,95 @@
+historyId = $historyId;
+ }
+ /**
+ * @return string
+ */
+ public function getHistoryId()
+ {
+ return $this->historyId;
+ }
+ /**
+ * @param string
+ */
+ public function setId($id)
+ {
+ $this->id = $id;
+ }
+ /**
+ * @return string
+ */
+ public function getId()
+ {
+ return $this->id;
+ }
+ /**
+ * @param Message[]
+ */
+ public function setMessages($messages)
+ {
+ $this->messages = $messages;
+ }
+ /**
+ * @return Message[]
+ */
+ public function getMessages()
+ {
+ return $this->messages;
+ }
+ /**
+ * @param string
+ */
+ public function setSnippet($snippet)
+ {
+ $this->snippet = $snippet;
+ }
+ /**
+ * @return string
+ */
+ public function getSnippet()
+ {
+ return $this->snippet;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(Thread::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_Thread');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/VacationSettings.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/VacationSettings.php
new file mode 100755
index 00000000..35d1150b
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/VacationSettings.php
@@ -0,0 +1,168 @@
+enableAutoReply = $enableAutoReply;
+ }
+ /**
+ * @return bool
+ */
+ public function getEnableAutoReply()
+ {
+ return $this->enableAutoReply;
+ }
+ /**
+ * @param string
+ */
+ public function setEndTime($endTime)
+ {
+ $this->endTime = $endTime;
+ }
+ /**
+ * @return string
+ */
+ public function getEndTime()
+ {
+ return $this->endTime;
+ }
+ /**
+ * @param string
+ */
+ public function setResponseBodyHtml($responseBodyHtml)
+ {
+ $this->responseBodyHtml = $responseBodyHtml;
+ }
+ /**
+ * @return string
+ */
+ public function getResponseBodyHtml()
+ {
+ return $this->responseBodyHtml;
+ }
+ /**
+ * @param string
+ */
+ public function setResponseBodyPlainText($responseBodyPlainText)
+ {
+ $this->responseBodyPlainText = $responseBodyPlainText;
+ }
+ /**
+ * @return string
+ */
+ public function getResponseBodyPlainText()
+ {
+ return $this->responseBodyPlainText;
+ }
+ /**
+ * @param string
+ */
+ public function setResponseSubject($responseSubject)
+ {
+ $this->responseSubject = $responseSubject;
+ }
+ /**
+ * @return string
+ */
+ public function getResponseSubject()
+ {
+ return $this->responseSubject;
+ }
+ /**
+ * @param bool
+ */
+ public function setRestrictToContacts($restrictToContacts)
+ {
+ $this->restrictToContacts = $restrictToContacts;
+ }
+ /**
+ * @return bool
+ */
+ public function getRestrictToContacts()
+ {
+ return $this->restrictToContacts;
+ }
+ /**
+ * @param bool
+ */
+ public function setRestrictToDomain($restrictToDomain)
+ {
+ $this->restrictToDomain = $restrictToDomain;
+ }
+ /**
+ * @return bool
+ */
+ public function getRestrictToDomain()
+ {
+ return $this->restrictToDomain;
+ }
+ /**
+ * @param string
+ */
+ public function setStartTime($startTime)
+ {
+ $this->startTime = $startTime;
+ }
+ /**
+ * @return string
+ */
+ public function getStartTime()
+ {
+ return $this->startTime;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(VacationSettings::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_VacationSettings');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/WatchRequest.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/WatchRequest.php
new file mode 100755
index 00000000..604e17a6
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/WatchRequest.php
@@ -0,0 +1,97 @@
+labelFilterAction = $labelFilterAction;
+ }
+ /**
+ * @return string
+ */
+ public function getLabelFilterAction()
+ {
+ return $this->labelFilterAction;
+ }
+ /**
+ * @param string
+ */
+ public function setLabelFilterBehavior($labelFilterBehavior)
+ {
+ $this->labelFilterBehavior = $labelFilterBehavior;
+ }
+ /**
+ * @return string
+ */
+ public function getLabelFilterBehavior()
+ {
+ return $this->labelFilterBehavior;
+ }
+ /**
+ * @param string[]
+ */
+ public function setLabelIds($labelIds)
+ {
+ $this->labelIds = $labelIds;
+ }
+ /**
+ * @return string[]
+ */
+ public function getLabelIds()
+ {
+ return $this->labelIds;
+ }
+ /**
+ * @param string
+ */
+ public function setTopicName($topicName)
+ {
+ $this->topicName = $topicName;
+ }
+ /**
+ * @return string
+ */
+ public function getTopicName()
+ {
+ return $this->topicName;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(WatchRequest::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_WatchRequest');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/WatchResponse.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/WatchResponse.php
new file mode 100755
index 00000000..e746058e
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient-services/src/Gmail/WatchResponse.php
@@ -0,0 +1,60 @@
+expiration = $expiration;
+ }
+ /**
+ * @return string
+ */
+ public function getExpiration()
+ {
+ return $this->expiration;
+ }
+ /**
+ * @param string
+ */
+ public function setHistoryId($historyId)
+ {
+ $this->historyId = $historyId;
+ }
+ /**
+ * @return string
+ */
+ public function getHistoryId()
+ {
+ return $this->historyId;
+ }
+}
+// Adding a class alias for backwards compatibility with the previous class name.
+\class_alias(WatchResponse::class, 'WPMailSMTP\\Vendor\\Google_Service_Gmail_WatchResponse');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/LICENSE b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/LICENSE
new file mode 100755
index 00000000..a148ba56
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/LICENSE
@@ -0,0 +1,203 @@
+Apache License
+Version 2.0, January 2004
+http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+"License" shall mean the terms and conditions for use, reproduction,
+and distribution as defined by Sections 1 through 9 of this document.
+
+"Licensor" shall mean the copyright owner or entity authorized by
+the copyright owner that is granting the License.
+
+"Legal Entity" shall mean the union of the acting entity and all
+other entities that control, are controlled by, or are under common
+control with that entity. For the purposes of this definition,
+"control" means (i) the power, direct or indirect, to cause the
+direction or management of such entity, whether by contract or
+otherwise, or (ii) ownership of fifty percent (50%) or more of the
+outstanding shares, or (iii) beneficial ownership of such entity.
+
+"You" (or "Your") shall mean an individual or Legal Entity
+exercising permissions granted by this License.
+
+"Source" form shall mean the preferred form for making modifications,
+including but not limited to software source code, documentation
+source, and configuration files.
+
+"Object" form shall mean any form resulting from mechanical
+transformation or translation of a Source form, including but
+not limited to compiled object code, generated documentation,
+and conversions to other media types.
+
+"Work" shall mean the work of authorship, whether in Source or
+Object form, made available under the License, as indicated by a
+copyright notice that is included in or attached to the work
+(an example is provided in the Appendix below).
+
+"Derivative Works" shall mean any work, whether in Source or Object
+form, that is based on (or derived from) the Work and for which the
+editorial revisions, annotations, elaborations, or other modifications
+represent, as a whole, an original work of authorship. For the purposes
+of this License, Derivative Works shall not include works that remain
+separable from, or merely link (or bind by name) to the interfaces of,
+the Work and Derivative Works thereof.
+
+"Contribution" shall mean any work of authorship, including
+the original version of the Work and any modifications or additions
+to that Work or Derivative Works thereof, that is intentionally
+submitted to Licensor for inclusion in the Work by the copyright owner
+or by an individual or Legal Entity authorized to submit on behalf of
+the copyright owner. For the purposes of this definition, "submitted"
+means any form of electronic, verbal, or written communication sent
+to the Licensor or its representatives, including but not limited to
+communication on electronic mailing lists, source code control systems,
+and issue tracking systems that are managed by, or on behalf of, the
+Licensor for the purpose of discussing and improving the Work, but
+excluding communication that is conspicuously marked or otherwise
+designated in writing by the copyright owner as "Not a Contribution."
+
+"Contributor" shall mean Licensor and any individual or Legal Entity
+on behalf of whom a Contribution has been received by Licensor and
+subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+this License, each Contributor hereby grants to You a perpetual,
+worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+copyright license to reproduce, prepare Derivative Works of,
+publicly display, publicly perform, sublicense, and distribute the
+Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+this License, each Contributor hereby grants to You a perpetual,
+worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+(except as stated in this section) patent license to make, have made,
+use, offer to sell, sell, import, and otherwise transfer the Work,
+where such license applies only to those patent claims licensable
+by such Contributor that are necessarily infringed by their
+Contribution(s) alone or by combination of their Contribution(s)
+with the Work to which such Contribution(s) was submitted. If You
+institute patent litigation against any entity (including a
+cross-claim or counterclaim in a lawsuit) alleging that the Work
+or a Contribution incorporated within the Work constitutes direct
+or contributory patent infringement, then any patent licenses
+granted to You under this License for that Work shall terminate
+as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+Work or Derivative Works thereof in any medium, with or without
+modifications, and in Source or Object form, provided that You
+meet the following conditions:
+
+(a) You must give any other recipients of the Work or
+Derivative Works a copy of this License; and
+
+(b) You must cause any modified files to carry prominent notices
+stating that You changed the files; and
+
+(c) You must retain, in the Source form of any Derivative Works
+that You distribute, all copyright, patent, trademark, and
+attribution notices from the Source form of the Work,
+excluding those notices that do not pertain to any part of
+the Derivative Works; and
+
+(d) If the Work includes a "NOTICE" text file as part of its
+distribution, then any Derivative Works that You distribute must
+include a readable copy of the attribution notices contained
+within such NOTICE file, excluding those notices that do not
+pertain to any part of the Derivative Works, in at least one
+of the following places: within a NOTICE text file distributed
+as part of the Derivative Works; within the Source form or
+documentation, if provided along with the Derivative Works; or,
+within a display generated by the Derivative Works, if and
+wherever such third-party notices normally appear. The contents
+of the NOTICE file are for informational purposes only and
+do not modify the License. You may add Your own attribution
+notices within Derivative Works that You distribute, alongside
+or as an addendum to the NOTICE text from the Work, provided
+that such additional attribution notices cannot be construed
+as modifying the License.
+
+You may add Your own copyright statement to Your modifications and
+may provide additional or different license terms and conditions
+for use, reproduction, or distribution of Your modifications, or
+for any such Derivative Works as a whole, provided Your use,
+reproduction, and distribution of the Work otherwise complies with
+the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+any Contribution intentionally submitted for inclusion in the Work
+by You to the Licensor shall be under the terms and conditions of
+this License, without any additional terms or conditions.
+Notwithstanding the above, nothing herein shall supersede or modify
+the terms of any separate license agreement you may have executed
+with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+names, trademarks, service marks, or product names of the Licensor,
+except as required for reasonable and customary use in describing the
+origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+agreed to in writing, Licensor provides the Work (and each
+Contributor provides its Contributions) on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+implied, including, without limitation, any warranties or conditions
+of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+PARTICULAR PURPOSE. You are solely responsible for determining the
+appropriateness of using or redistributing the Work and assume any
+risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+whether in tort (including negligence), contract, or otherwise,
+unless required by applicable law (such as deliberate and grossly
+negligent acts) or agreed to in writing, shall any Contributor be
+liable to You for damages, including any direct, indirect, special,
+incidental, or consequential damages of any character arising as a
+result of this License or out of the use or inability to use the
+Work (including but not limited to damages for loss of goodwill,
+work stoppage, computer failure or malfunction, or any and all
+other commercial damages or losses), even if such Contributor
+has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+the Work or Derivative Works thereof, You may choose to offer,
+and charge a fee for, acceptance of support, warranty, indemnity,
+or other liability obligations and/or rights consistent with this
+License. However, in accepting such obligations, You may act only
+on Your own behalf and on Your sole responsibility, not on behalf
+of any other Contributor, and only if You agree to indemnify,
+defend, and hold each Contributor harmless for any liability
+incurred by, or claims asserted against, such Contributor by reason
+of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+To apply the Apache License to your work, attach the following
+boilerplate notice, with the fields enclosed by brackets "[]"
+replaced with your own identifying information. (Don't include
+the brackets!) The text should be enclosed in the appropriate
+comment syntax for the file format. We also recommend that a
+file or class name and description of purpose be included on the
+same "printed page" as the copyright notice for easier
+identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/AccessToken/Revoke.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/AccessToken/Revoke.php
new file mode 100755
index 00000000..7e965493
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/AccessToken/Revoke.php
@@ -0,0 +1,65 @@
+http = $http;
+ }
+ /**
+ * Revoke an OAuth2 access token or refresh token. This method will revoke the current access
+ * token, if a token isn't provided.
+ *
+ * @param string|array $token The token (access token or a refresh token) that should be revoked.
+ * @return boolean Returns True if the revocation was successful, otherwise False.
+ */
+ public function revokeToken($token)
+ {
+ if (\is_array($token)) {
+ if (isset($token['refresh_token'])) {
+ $token = $token['refresh_token'];
+ } else {
+ $token = $token['access_token'];
+ }
+ }
+ $body = Psr7\Utils::streamFor(\http_build_query(['token' => $token]));
+ $request = new Request('POST', Client::OAUTH2_REVOKE_URI, ['Cache-Control' => 'no-store', 'Content-Type' => 'application/x-www-form-urlencoded'], $body);
+ $httpHandler = HttpHandlerFactory::build($this->http);
+ $response = $httpHandler($request);
+ return $response->getStatusCode() == 200;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/AccessToken/Verify.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/AccessToken/Verify.php
new file mode 100755
index 00000000..86c0490b
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/AccessToken/Verify.php
@@ -0,0 +1,217 @@
+http = $http;
+ $this->cache = $cache;
+ $this->jwt = $jwt ?: $this->getJwtService();
+ }
+ /**
+ * Verifies an id token and returns the authenticated apiLoginTicket.
+ * Throws an exception if the id token is not valid.
+ * The audience parameter can be used to control which id tokens are
+ * accepted. By default, the id token must have been issued to this OAuth2 client.
+ *
+ * @param string $idToken the ID token in JWT format
+ * @param string $audience Optional. The audience to verify against JWt "aud"
+ * @return array|false the token payload, if successful
+ */
+ public function verifyIdToken($idToken, $audience = null)
+ {
+ if (empty($idToken)) {
+ throw new LogicException('id_token cannot be null');
+ }
+ // set phpseclib constants if applicable
+ $this->setPhpsecConstants();
+ // Check signature
+ $certs = $this->getFederatedSignOnCerts();
+ foreach ($certs as $cert) {
+ try {
+ $args = [$idToken];
+ $publicKey = $this->getPublicKey($cert);
+ if (\class_exists(Key::class)) {
+ $args[] = new Key($publicKey, 'RS256');
+ } else {
+ $args[] = $publicKey;
+ $args[] = ['RS256'];
+ }
+ $payload = \call_user_func_array([$this->jwt, 'decode'], $args);
+ if (\property_exists($payload, 'aud')) {
+ if ($audience && $payload->aud != $audience) {
+ return \false;
+ }
+ }
+ // support HTTP and HTTPS issuers
+ // @see https://developers.google.com/identity/sign-in/web/backend-auth
+ $issuers = [self::OAUTH2_ISSUER, self::OAUTH2_ISSUER_HTTPS];
+ if (!isset($payload->iss) || !\in_array($payload->iss, $issuers)) {
+ return \false;
+ }
+ return (array) $payload;
+ } catch (ExpiredException $e) {
+ // @phpstan-ignore-line
+ return \false;
+ } catch (ExpiredExceptionV3 $e) {
+ return \false;
+ } catch (SignatureInvalidException $e) {
+ // continue
+ } catch (DomainException $e) {
+ // continue
+ }
+ }
+ return \false;
+ }
+ private function getCache()
+ {
+ return $this->cache;
+ }
+ /**
+ * Retrieve and cache a certificates file.
+ *
+ * @param string $url location
+ * @throws \Google\Exception
+ * @return array certificates
+ */
+ private function retrieveCertsFromLocation($url)
+ {
+ // If we're retrieving a local file, just grab it.
+ if (0 !== \strpos($url, 'http')) {
+ if (!($file = \file_get_contents($url))) {
+ throw new GoogleException("Failed to retrieve verification certificates: '" . $url . "'.");
+ }
+ return \json_decode($file, \true);
+ }
+ // @phpstan-ignore-next-line
+ $response = $this->http->get($url);
+ if ($response->getStatusCode() == 200) {
+ return \json_decode((string) $response->getBody(), \true);
+ }
+ throw new GoogleException(\sprintf('Failed to retrieve verification certificates: "%s".', $response->getBody()->getContents()), $response->getStatusCode());
+ }
+ // Gets federated sign-on certificates to use for verifying identity tokens.
+ // Returns certs as array structure, where keys are key ids, and values
+ // are PEM encoded certificates.
+ private function getFederatedSignOnCerts()
+ {
+ $certs = null;
+ if ($cache = $this->getCache()) {
+ $cacheItem = $cache->getItem('federated_signon_certs_v3');
+ $certs = $cacheItem->get();
+ }
+ if (!$certs) {
+ $certs = $this->retrieveCertsFromLocation(self::FEDERATED_SIGNON_CERT_URL);
+ if ($cache) {
+ $cacheItem->expiresAt(new DateTime('+1 hour'));
+ $cacheItem->set($certs);
+ $cache->save($cacheItem);
+ }
+ }
+ if (!isset($certs['keys'])) {
+ throw new InvalidArgumentException('federated sign-on certs expects "keys" to be set');
+ }
+ return $certs['keys'];
+ }
+ private function getJwtService()
+ {
+ $jwt = new JWT();
+ if ($jwt::$leeway < 1) {
+ // Ensures JWT leeway is at least 1
+ // @see https://github.com/google/google-api-php-client/issues/827
+ $jwt::$leeway = 1;
+ }
+ return $jwt;
+ }
+ private function getPublicKey($cert)
+ {
+ $modulus = new BigInteger($this->jwt->urlsafeB64Decode($cert['n']), 256);
+ $exponent = new BigInteger($this->jwt->urlsafeB64Decode($cert['e']), 256);
+ $component = ['n' => $modulus, 'e' => $exponent];
+ $loader = PublicKeyLoader::load($component);
+ return $loader->toString('PKCS8');
+ }
+ /**
+ * phpseclib calls "phpinfo" by default, which requires special
+ * whitelisting in the AppEngine VM environment. This function
+ * sets constants to bypass the need for phpseclib to check phpinfo
+ *
+ * @see phpseclib/Math/BigInteger
+ * @see https://github.com/GoogleCloudPlatform/getting-started-php/issues/85
+ */
+ private function setPhpsecConstants()
+ {
+ if (\filter_var(\getenv('GAE_VM'), \FILTER_VALIDATE_BOOLEAN)) {
+ if (!\defined('WPMailSMTP\\Vendor\\MATH_BIGINTEGER_OPENSSL_ENABLED')) {
+ \define('WPMailSMTP\\Vendor\\MATH_BIGINTEGER_OPENSSL_ENABLED', \true);
+ }
+ if (!\defined('WPMailSMTP\\Vendor\\CRYPT_RSA_MODE')) {
+ \define('WPMailSMTP\\Vendor\\CRYPT_RSA_MODE', AES::ENGINE_OPENSSL);
+ }
+ }
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/AuthHandler/AuthHandlerFactory.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/AuthHandler/AuthHandlerFactory.php
new file mode 100755
index 00000000..06a41454
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/AuthHandler/AuthHandlerFactory.php
@@ -0,0 +1,47 @@
+cache = $cache;
+ $this->cacheConfig = $cacheConfig;
+ }
+ public function attachCredentials(ClientInterface $http, CredentialsLoader $credentials, ?callable $tokenCallback = null)
+ {
+ // use the provided cache
+ if ($this->cache) {
+ $credentials = new FetchAuthTokenCache($credentials, $this->cacheConfig, $this->cache);
+ }
+ return $this->attachCredentialsCache($http, $credentials, $tokenCallback);
+ }
+ public function attachCredentialsCache(ClientInterface $http, FetchAuthTokenCache $credentials, ?callable $tokenCallback = null)
+ {
+ // if we end up needing to make an HTTP request to retrieve credentials, we
+ // can use our existing one, but we need to throw exceptions so the error
+ // bubbles up.
+ $authHttp = $this->createAuthHttp($http);
+ $authHttpHandler = HttpHandlerFactory::build($authHttp);
+ $middleware = new AuthTokenMiddleware($credentials, $authHttpHandler, $tokenCallback);
+ $config = $http->getConfig();
+ $config['handler']->remove('google_auth');
+ $config['handler']->push($middleware, 'google_auth');
+ $config['auth'] = 'google_auth';
+ $http = new Client($config);
+ return $http;
+ }
+ public function attachToken(ClientInterface $http, array $token, array $scopes)
+ {
+ $tokenFunc = function ($scopes) use($token) {
+ return $token['access_token'];
+ };
+ $middleware = new ScopedAccessTokenMiddleware($tokenFunc, $scopes, $this->cacheConfig, $this->cache);
+ $config = $http->getConfig();
+ $config['handler']->remove('google_auth');
+ $config['handler']->push($middleware, 'google_auth');
+ $config['auth'] = 'scoped';
+ $http = new Client($config);
+ return $http;
+ }
+ public function attachKey(ClientInterface $http, $key)
+ {
+ $middleware = new SimpleMiddleware(['key' => $key]);
+ $config = $http->getConfig();
+ $config['handler']->remove('google_auth');
+ $config['handler']->push($middleware, 'google_auth');
+ $config['auth'] = 'simple';
+ $http = new Client($config);
+ return $http;
+ }
+ private function createAuthHttp(ClientInterface $http)
+ {
+ return new Client(['http_errors' => \true] + $http->getConfig());
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/AuthHandler/Guzzle7AuthHandler.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/AuthHandler/Guzzle7AuthHandler.php
new file mode 100755
index 00000000..b09d1810
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/AuthHandler/Guzzle7AuthHandler.php
@@ -0,0 +1,25 @@
+config = \array_merge(['application_name' => '', 'base_path' => self::API_BASE_PATH, 'client_id' => '', 'client_secret' => '', 'credentials' => null, 'scopes' => null, 'quota_project' => null, 'redirect_uri' => null, 'state' => null, 'developer_key' => '', 'use_application_default_credentials' => \false, 'signing_key' => null, 'signing_algorithm' => null, 'subject' => null, 'hd' => '', 'prompt' => '', 'openid.realm' => '', 'include_granted_scopes' => null, 'login_hint' => '', 'request_visible_actions' => '', 'access_type' => 'online', 'approval_prompt' => 'auto', 'retry' => [], 'retry_map' => null, 'cache' => null, 'cache_config' => [], 'token_callback' => null, 'jwt' => null, 'api_format_v2' => \false, 'universe_domain' => \getenv('GOOGLE_CLOUD_UNIVERSE_DOMAIN') ?: GetUniverseDomainInterface::DEFAULT_UNIVERSE_DOMAIN], $config);
+ if (!\is_null($this->config['credentials'])) {
+ if ($this->config['credentials'] instanceof CredentialsLoader) {
+ $this->credentials = $this->config['credentials'];
+ } else {
+ $this->setAuthConfig($this->config['credentials']);
+ }
+ unset($this->config['credentials']);
+ }
+ if (!\is_null($this->config['scopes'])) {
+ $this->setScopes($this->config['scopes']);
+ unset($this->config['scopes']);
+ }
+ // Set a default token callback to update the in-memory access token
+ if (\is_null($this->config['token_callback'])) {
+ $this->config['token_callback'] = function ($cacheKey, $newAccessToken) {
+ $this->setAccessToken([
+ 'access_token' => $newAccessToken,
+ 'expires_in' => 3600,
+ // Google default
+ 'created' => \time(),
+ ]);
+ };
+ }
+ if (!\is_null($this->config['cache'])) {
+ $this->setCache($this->config['cache']);
+ unset($this->config['cache']);
+ }
+ }
+ /**
+ * Get a string containing the version of the library.
+ *
+ * @return string
+ */
+ public function getLibraryVersion()
+ {
+ return self::LIBVER;
+ }
+ /**
+ * For backwards compatibility
+ * alias for fetchAccessTokenWithAuthCode
+ *
+ * @param string $code string code from accounts.google.com
+ * @return array access token
+ * @deprecated
+ */
+ public function authenticate($code)
+ {
+ return $this->fetchAccessTokenWithAuthCode($code);
+ }
+ /**
+ * Attempt to exchange a code for an valid authentication token.
+ * Helper wrapped around the OAuth 2.0 implementation.
+ *
+ * @param string $code code from accounts.google.com
+ * @param string $codeVerifier the code verifier used for PKCE (if applicable)
+ * @return array access token
+ */
+ public function fetchAccessTokenWithAuthCode($code, $codeVerifier = null)
+ {
+ if (\strlen($code) == 0) {
+ throw new InvalidArgumentException("Invalid code");
+ }
+ $auth = $this->getOAuth2Service();
+ $auth->setCode($code);
+ $auth->setRedirectUri($this->getRedirectUri());
+ if ($codeVerifier) {
+ $auth->setCodeVerifier($codeVerifier);
+ }
+ $httpHandler = HttpHandlerFactory::build($this->getHttpClient());
+ $creds = $auth->fetchAuthToken($httpHandler);
+ if ($creds && isset($creds['access_token'])) {
+ $creds['created'] = \time();
+ $this->setAccessToken($creds);
+ }
+ return $creds;
+ }
+ /**
+ * For backwards compatibility
+ * alias for fetchAccessTokenWithAssertion
+ *
+ * @return array access token
+ * @deprecated
+ */
+ public function refreshTokenWithAssertion()
+ {
+ return $this->fetchAccessTokenWithAssertion();
+ }
+ /**
+ * Fetches a fresh access token with a given assertion token.
+ * @param ClientInterface $authHttp optional.
+ * @return array access token
+ */
+ public function fetchAccessTokenWithAssertion(?ClientInterface $authHttp = null)
+ {
+ if (!$this->isUsingApplicationDefaultCredentials()) {
+ throw new DomainException('set the JSON service account credentials using' . ' Google\\Client::setAuthConfig or set the path to your JSON file' . ' with the "GOOGLE_APPLICATION_CREDENTIALS" environment variable' . ' and call Google\\Client::useApplicationDefaultCredentials to' . ' refresh a token with assertion.');
+ }
+ $this->getLogger()->log('info', 'OAuth2 access token refresh with Signed JWT assertion grants.');
+ $credentials = $this->createApplicationDefaultCredentials();
+ $httpHandler = HttpHandlerFactory::build($authHttp);
+ $creds = $credentials->fetchAuthToken($httpHandler);
+ if ($creds && isset($creds['access_token'])) {
+ $creds['created'] = \time();
+ $this->setAccessToken($creds);
+ }
+ return $creds;
+ }
+ /**
+ * For backwards compatibility
+ * alias for fetchAccessTokenWithRefreshToken
+ *
+ * @param string $refreshToken
+ * @return array access token
+ */
+ public function refreshToken($refreshToken)
+ {
+ return $this->fetchAccessTokenWithRefreshToken($refreshToken);
+ }
+ /**
+ * Fetches a fresh OAuth 2.0 access token with the given refresh token.
+ * @param string $refreshToken
+ * @return array access token
+ */
+ public function fetchAccessTokenWithRefreshToken($refreshToken = null)
+ {
+ if (null === $refreshToken) {
+ if (!isset($this->token['refresh_token'])) {
+ throw new LogicException('refresh token must be passed in or set as part of setAccessToken');
+ }
+ $refreshToken = $this->token['refresh_token'];
+ }
+ $this->getLogger()->info('OAuth2 access token refresh');
+ $auth = $this->getOAuth2Service();
+ $auth->setRefreshToken($refreshToken);
+ $httpHandler = HttpHandlerFactory::build($this->getHttpClient());
+ $creds = $auth->fetchAuthToken($httpHandler);
+ if ($creds && isset($creds['access_token'])) {
+ $creds['created'] = \time();
+ if (!isset($creds['refresh_token'])) {
+ $creds['refresh_token'] = $refreshToken;
+ }
+ $this->setAccessToken($creds);
+ }
+ return $creds;
+ }
+ /**
+ * Create a URL to obtain user authorization.
+ * The authorization endpoint allows the user to first
+ * authenticate, and then grant/deny the access request.
+ * @param string|array $scope The scope is expressed as an array or list of space-delimited strings.
+ * @param array $queryParams Querystring params to add to the authorization URL.
+ * @return string
+ */
+ public function createAuthUrl($scope = null, array $queryParams = [])
+ {
+ if (empty($scope)) {
+ $scope = $this->prepareScopes();
+ }
+ if (\is_array($scope)) {
+ $scope = \implode(' ', $scope);
+ }
+ // only accept one of prompt or approval_prompt
+ $approvalPrompt = $this->config['prompt'] ? null : $this->config['approval_prompt'];
+ // include_granted_scopes should be string "true", string "false", or null
+ $includeGrantedScopes = $this->config['include_granted_scopes'] === null ? null : \var_export($this->config['include_granted_scopes'], \true);
+ $params = \array_filter(['access_type' => $this->config['access_type'], 'approval_prompt' => $approvalPrompt, 'hd' => $this->config['hd'], 'include_granted_scopes' => $includeGrantedScopes, 'login_hint' => $this->config['login_hint'], 'openid.realm' => $this->config['openid.realm'], 'prompt' => $this->config['prompt'], 'redirect_uri' => $this->config['redirect_uri'], 'response_type' => 'code', 'scope' => $scope, 'state' => $this->config['state']]) + $queryParams;
+ // If the list of scopes contains plus.login, add request_visible_actions
+ // to auth URL.
+ $rva = $this->config['request_visible_actions'];
+ if (\strlen($rva) > 0 && \false !== \strpos($scope, 'plus.login')) {
+ $params['request_visible_actions'] = $rva;
+ }
+ $auth = $this->getOAuth2Service();
+ return (string) $auth->buildFullAuthorizationUri($params);
+ }
+ /**
+ * Adds auth listeners to the HTTP client based on the credentials
+ * set in the Google API Client object
+ *
+ * @param ClientInterface $http the http client object.
+ * @return ClientInterface the http client object
+ */
+ public function authorize(?ClientInterface $http = null)
+ {
+ $http = $http ?: $this->getHttpClient();
+ $authHandler = $this->getAuthHandler();
+ // These conditionals represent the decision tree for authentication
+ // 1. Check if a Google\Auth\CredentialsLoader instance has been supplied via the "credentials" option
+ // 2. Check for Application Default Credentials
+ // 3a. Check for an Access Token
+ // 3b. If access token exists but is expired, try to refresh it
+ // 4. Check for API Key
+ if ($this->credentials) {
+ $this->checkUniverseDomain($this->credentials);
+ return $authHandler->attachCredentials($http, $this->credentials, $this->config['token_callback']);
+ }
+ if ($this->isUsingApplicationDefaultCredentials()) {
+ $credentials = $this->createApplicationDefaultCredentials();
+ $this->checkUniverseDomain($credentials);
+ return $authHandler->attachCredentialsCache($http, $credentials, $this->config['token_callback']);
+ }
+ if ($token = $this->getAccessToken()) {
+ $scopes = $this->prepareScopes();
+ // add refresh subscriber to request a new token
+ if (isset($token['refresh_token']) && $this->isAccessTokenExpired()) {
+ $credentials = $this->createUserRefreshCredentials($scopes, $token['refresh_token']);
+ $this->checkUniverseDomain($credentials);
+ return $authHandler->attachCredentials($http, $credentials, $this->config['token_callback']);
+ }
+ return $authHandler->attachToken($http, $token, (array) $scopes);
+ }
+ if ($key = $this->config['developer_key']) {
+ return $authHandler->attachKey($http, $key);
+ }
+ return $http;
+ }
+ /**
+ * Set the configuration to use application default credentials for
+ * authentication
+ *
+ * @see https://developers.google.com/identity/protocols/application-default-credentials
+ * @param boolean $useAppCreds
+ */
+ public function useApplicationDefaultCredentials($useAppCreds = \true)
+ {
+ $this->config['use_application_default_credentials'] = $useAppCreds;
+ }
+ /**
+ * To prevent useApplicationDefaultCredentials from inappropriately being
+ * called in a conditional
+ *
+ * @see https://developers.google.com/identity/protocols/application-default-credentials
+ */
+ public function isUsingApplicationDefaultCredentials()
+ {
+ return $this->config['use_application_default_credentials'];
+ }
+ /**
+ * Set the access token used for requests.
+ *
+ * Note that at the time requests are sent, tokens are cached. A token will be
+ * cached for each combination of service and authentication scopes. If a
+ * cache pool is not provided, creating a new instance of the client will
+ * allow modification of access tokens. If a persistent cache pool is
+ * provided, in order to change the access token, you must clear the cached
+ * token by calling `$client->getCache()->clear()`. (Use caution in this case,
+ * as calling `clear()` will remove all cache items, including any items not
+ * related to Google API PHP Client.)
+ *
+ * **NOTE:** The universe domain is assumed to be "googleapis.com" unless
+ * explicitly set. When setting an access token directly via this method, there
+ * is no way to verify the universe domain. Be sure to set the "universe_domain"
+ * option if "googleapis.com" is not intended.
+ *
+ * @param string|array $token
+ * @throws InvalidArgumentException
+ */
+ public function setAccessToken($token)
+ {
+ if (\is_string($token)) {
+ if ($json = \json_decode($token, \true)) {
+ $token = $json;
+ } else {
+ // assume $token is just the token string
+ $token = ['access_token' => $token];
+ }
+ }
+ if ($token == null) {
+ throw new InvalidArgumentException('invalid json token');
+ }
+ if (!isset($token['access_token'])) {
+ throw new InvalidArgumentException("Invalid token format");
+ }
+ $this->token = $token;
+ }
+ public function getAccessToken()
+ {
+ return $this->token;
+ }
+ /**
+ * @return string|null
+ */
+ public function getRefreshToken()
+ {
+ if (isset($this->token['refresh_token'])) {
+ return $this->token['refresh_token'];
+ }
+ return null;
+ }
+ /**
+ * Returns if the access_token is expired.
+ * @return bool Returns True if the access_token is expired.
+ */
+ public function isAccessTokenExpired()
+ {
+ if (!$this->token) {
+ return \true;
+ }
+ $created = 0;
+ if (isset($this->token['created'])) {
+ $created = $this->token['created'];
+ } elseif (isset($this->token['id_token'])) {
+ // check the ID token for "iat"
+ // signature verification is not required here, as we are just
+ // using this for convenience to save a round trip request
+ // to the Google API server
+ $idToken = $this->token['id_token'];
+ if (\substr_count($idToken, '.') == 2) {
+ $parts = \explode('.', $idToken);
+ $payload = \json_decode(\base64_decode($parts[1]), \true);
+ if ($payload && isset($payload['iat'])) {
+ $created = $payload['iat'];
+ }
+ }
+ }
+ if (!isset($this->token['expires_in'])) {
+ // if the token does not have an "expires_in", then it's considered expired
+ return \true;
+ }
+ // If the token is set to expire in the next 30 seconds.
+ return $created + ($this->token['expires_in'] - 30) < \time();
+ }
+ /**
+ * @deprecated See UPGRADING.md for more information
+ */
+ public function getAuth()
+ {
+ throw new BadMethodCallException('This function no longer exists. See UPGRADING.md for more information');
+ }
+ /**
+ * @deprecated See UPGRADING.md for more information
+ */
+ public function setAuth($auth)
+ {
+ throw new BadMethodCallException('This function no longer exists. See UPGRADING.md for more information');
+ }
+ /**
+ * Set the OAuth 2.0 Client ID.
+ * @param string $clientId
+ */
+ public function setClientId($clientId)
+ {
+ $this->config['client_id'] = $clientId;
+ }
+ public function getClientId()
+ {
+ return $this->config['client_id'];
+ }
+ /**
+ * Set the OAuth 2.0 Client Secret.
+ * @param string $clientSecret
+ */
+ public function setClientSecret($clientSecret)
+ {
+ $this->config['client_secret'] = $clientSecret;
+ }
+ public function getClientSecret()
+ {
+ return $this->config['client_secret'];
+ }
+ /**
+ * Set the OAuth 2.0 Redirect URI.
+ * @param string $redirectUri
+ */
+ public function setRedirectUri($redirectUri)
+ {
+ $this->config['redirect_uri'] = $redirectUri;
+ }
+ public function getRedirectUri()
+ {
+ return $this->config['redirect_uri'];
+ }
+ /**
+ * Set OAuth 2.0 "state" parameter to achieve per-request customization.
+ * @see http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-3.1.2.2
+ * @param string $state
+ */
+ public function setState($state)
+ {
+ $this->config['state'] = $state;
+ }
+ /**
+ * @param string $accessType Possible values for access_type include:
+ * {@code "offline"} to request offline access from the user.
+ * {@code "online"} to request online access from the user.
+ */
+ public function setAccessType($accessType)
+ {
+ $this->config['access_type'] = $accessType;
+ }
+ /**
+ * @param string $approvalPrompt Possible values for approval_prompt include:
+ * {@code "force"} to force the approval UI to appear.
+ * {@code "auto"} to request auto-approval when possible. (This is the default value)
+ */
+ public function setApprovalPrompt($approvalPrompt)
+ {
+ $this->config['approval_prompt'] = $approvalPrompt;
+ }
+ /**
+ * Set the login hint, email address or sub id.
+ * @param string $loginHint
+ */
+ public function setLoginHint($loginHint)
+ {
+ $this->config['login_hint'] = $loginHint;
+ }
+ /**
+ * Set the application name, this is included in the User-Agent HTTP header.
+ * @param string $applicationName
+ */
+ public function setApplicationName($applicationName)
+ {
+ $this->config['application_name'] = $applicationName;
+ }
+ /**
+ * If 'plus.login' is included in the list of requested scopes, you can use
+ * this method to define types of app activities that your app will write.
+ * You can find a list of available types here:
+ * @link https://developers.google.com/+/api/moment-types
+ *
+ * @param array $requestVisibleActions Array of app activity types
+ */
+ public function setRequestVisibleActions($requestVisibleActions)
+ {
+ if (\is_array($requestVisibleActions)) {
+ $requestVisibleActions = \implode(" ", $requestVisibleActions);
+ }
+ $this->config['request_visible_actions'] = $requestVisibleActions;
+ }
+ /**
+ * Set the developer key to use, these are obtained through the API Console.
+ * @see http://code.google.com/apis/console-help/#generatingdevkeys
+ * @param string $developerKey
+ */
+ public function setDeveloperKey($developerKey)
+ {
+ $this->config['developer_key'] = $developerKey;
+ }
+ /**
+ * Set the hd (hosted domain) parameter streamlines the login process for
+ * Google Apps hosted accounts. By including the domain of the user, you
+ * restrict sign-in to accounts at that domain.
+ * @param string $hd the domain to use.
+ */
+ public function setHostedDomain($hd)
+ {
+ $this->config['hd'] = $hd;
+ }
+ /**
+ * Set the prompt hint. Valid values are none, consent and select_account.
+ * If no value is specified and the user has not previously authorized
+ * access, then the user is shown a consent screen.
+ * @param string $prompt
+ * {@code "none"} Do not display any authentication or consent screens. Must not be specified with other values.
+ * {@code "consent"} Prompt the user for consent.
+ * {@code "select_account"} Prompt the user to select an account.
+ */
+ public function setPrompt($prompt)
+ {
+ $this->config['prompt'] = $prompt;
+ }
+ /**
+ * openid.realm is a parameter from the OpenID 2.0 protocol, not from OAuth
+ * 2.0. It is used in OpenID 2.0 requests to signify the URL-space for which
+ * an authentication request is valid.
+ * @param string $realm the URL-space to use.
+ */
+ public function setOpenidRealm($realm)
+ {
+ $this->config['openid.realm'] = $realm;
+ }
+ /**
+ * If this is provided with the value true, and the authorization request is
+ * granted, the authorization will include any previous authorizations
+ * granted to this user/application combination for other scopes.
+ * @param bool $include the URL-space to use.
+ */
+ public function setIncludeGrantedScopes($include)
+ {
+ $this->config['include_granted_scopes'] = $include;
+ }
+ /**
+ * sets function to be called when an access token is fetched
+ * @param callable $tokenCallback - function ($cacheKey, $accessToken)
+ */
+ public function setTokenCallback(callable $tokenCallback)
+ {
+ $this->config['token_callback'] = $tokenCallback;
+ }
+ /**
+ * Revoke an OAuth2 access token or refresh token. This method will revoke the current access
+ * token, if a token isn't provided.
+ *
+ * @param string|array|null $token The token (access token or a refresh token) that should be revoked.
+ * @return boolean Returns True if the revocation was successful, otherwise False.
+ */
+ public function revokeToken($token = null)
+ {
+ $tokenRevoker = new Revoke($this->getHttpClient());
+ return $tokenRevoker->revokeToken($token ?: $this->getAccessToken());
+ }
+ /**
+ * Verify an id_token. This method will verify the current id_token, if one
+ * isn't provided.
+ *
+ * @throws LogicException If no token was provided and no token was set using `setAccessToken`.
+ * @throws UnexpectedValueException If the token is not a valid JWT.
+ * @param string|null $idToken The token (id_token) that should be verified.
+ * @return array|false Returns the token payload as an array if the verification was
+ * successful, false otherwise.
+ */
+ public function verifyIdToken($idToken = null)
+ {
+ $tokenVerifier = new Verify($this->getHttpClient(), $this->getCache(), $this->config['jwt']);
+ if (null === $idToken) {
+ $token = $this->getAccessToken();
+ if (!isset($token['id_token'])) {
+ throw new LogicException('id_token must be passed in or set as part of setAccessToken');
+ }
+ $idToken = $token['id_token'];
+ }
+ return $tokenVerifier->verifyIdToken($idToken, $this->getClientId());
+ }
+ /**
+ * Set the scopes to be requested. Must be called before createAuthUrl().
+ * Will remove any previously configured scopes.
+ * @param string|array $scope_or_scopes, ie:
+ * array(
+ * 'https://www.googleapis.com/auth/plus.login',
+ * 'https://www.googleapis.com/auth/moderator'
+ * );
+ */
+ public function setScopes($scope_or_scopes)
+ {
+ $this->requestedScopes = [];
+ $this->addScope($scope_or_scopes);
+ }
+ /**
+ * This functions adds a scope to be requested as part of the OAuth2.0 flow.
+ * Will append any scopes not previously requested to the scope parameter.
+ * A single string will be treated as a scope to request. An array of strings
+ * will each be appended.
+ * @param string|string[] $scope_or_scopes e.g. "profile"
+ */
+ public function addScope($scope_or_scopes)
+ {
+ if (\is_string($scope_or_scopes) && !\in_array($scope_or_scopes, $this->requestedScopes)) {
+ $this->requestedScopes[] = $scope_or_scopes;
+ } elseif (\is_array($scope_or_scopes)) {
+ foreach ($scope_or_scopes as $scope) {
+ $this->addScope($scope);
+ }
+ }
+ }
+ /**
+ * Returns the list of scopes requested by the client
+ * @return array the list of scopes
+ *
+ */
+ public function getScopes()
+ {
+ return $this->requestedScopes;
+ }
+ /**
+ * @return string|null
+ * @visible For Testing
+ */
+ public function prepareScopes()
+ {
+ if (empty($this->requestedScopes)) {
+ return null;
+ }
+ return \implode(' ', $this->requestedScopes);
+ }
+ /**
+ * Helper method to execute deferred HTTP requests.
+ *
+ * @template T
+ * @param RequestInterface $request
+ * @param class-string|false|null $expectedClass
+ * @throws \Google\Exception
+ * @return mixed|T|ResponseInterface
+ */
+ public function execute(RequestInterface $request, $expectedClass = null)
+ {
+ $request = $request->withHeader('User-Agent', \sprintf('%s %s%s', $this->config['application_name'], self::USER_AGENT_SUFFIX, $this->getLibraryVersion()))->withHeader('x-goog-api-client', \sprintf('gl-php/%s gdcl/%s', \phpversion(), $this->getLibraryVersion()));
+ if ($this->config['api_format_v2']) {
+ $request = $request->withHeader('X-GOOG-API-FORMAT-VERSION', '2');
+ }
+ // call the authorize method
+ // this is where most of the grunt work is done
+ $http = $this->authorize();
+ return REST::execute($http, $request, $expectedClass, $this->config['retry'], $this->config['retry_map']);
+ }
+ /**
+ * Declare whether batch calls should be used. This may increase throughput
+ * by making multiple requests in one connection.
+ *
+ * @param boolean $useBatch True if the batch support should
+ * be enabled. Defaults to False.
+ */
+ public function setUseBatch($useBatch)
+ {
+ // This is actually an alias for setDefer.
+ $this->setDefer($useBatch);
+ }
+ /**
+ * Are we running in Google AppEngine?
+ * return bool
+ */
+ public function isAppEngine()
+ {
+ return isset($_SERVER['SERVER_SOFTWARE']) && \strpos($_SERVER['SERVER_SOFTWARE'], 'Google App Engine') !== \false;
+ }
+ public function setConfig($name, $value)
+ {
+ $this->config[$name] = $value;
+ }
+ public function getConfig($name, $default = null)
+ {
+ return isset($this->config[$name]) ? $this->config[$name] : $default;
+ }
+ /**
+ * For backwards compatibility
+ * alias for setAuthConfig
+ *
+ * @param string $file the configuration file
+ * @throws \Google\Exception
+ * @deprecated
+ */
+ public function setAuthConfigFile($file)
+ {
+ $this->setAuthConfig($file);
+ }
+ /**
+ * Set the auth config from new or deprecated JSON config.
+ * This structure should match the file downloaded from
+ * the "Download JSON" button on in the Google Developer
+ * Console.
+ * @param string|array $config the configuration json
+ * @throws \Google\Exception
+ */
+ public function setAuthConfig($config)
+ {
+ if (\is_string($config)) {
+ if (!\file_exists($config)) {
+ throw new InvalidArgumentException(\sprintf('file "%s" does not exist', $config));
+ }
+ $json = \file_get_contents($config);
+ if (!($config = \json_decode($json, \true))) {
+ throw new LogicException('invalid json for auth config');
+ }
+ }
+ $key = isset($config['installed']) ? 'installed' : 'web';
+ if (isset($config['type']) && $config['type'] == 'service_account') {
+ // application default credentials
+ $this->useApplicationDefaultCredentials();
+ // set the information from the config
+ $this->setClientId($config['client_id']);
+ $this->config['client_email'] = $config['client_email'];
+ $this->config['signing_key'] = $config['private_key'];
+ $this->config['signing_algorithm'] = 'HS256';
+ } elseif (isset($config[$key])) {
+ // old-style
+ $this->setClientId($config[$key]['client_id']);
+ $this->setClientSecret($config[$key]['client_secret']);
+ if (isset($config[$key]['redirect_uris'])) {
+ $this->setRedirectUri($config[$key]['redirect_uris'][0]);
+ }
+ } else {
+ // new-style
+ $this->setClientId($config['client_id']);
+ $this->setClientSecret($config['client_secret']);
+ if (isset($config['redirect_uris'])) {
+ $this->setRedirectUri($config['redirect_uris'][0]);
+ }
+ }
+ }
+ /**
+ * Use when the service account has been delegated domain wide access.
+ *
+ * @param string $subject an email address account to impersonate
+ */
+ public function setSubject($subject)
+ {
+ $this->config['subject'] = $subject;
+ }
+ /**
+ * Declare whether making API calls should make the call immediately, or
+ * return a request which can be called with ->execute();
+ *
+ * @param boolean $defer True if calls should not be executed right away.
+ */
+ public function setDefer($defer)
+ {
+ $this->deferExecution = $defer;
+ }
+ /**
+ * Whether or not to return raw requests
+ * @return boolean
+ */
+ public function shouldDefer()
+ {
+ return $this->deferExecution;
+ }
+ /**
+ * @return OAuth2 implementation
+ */
+ public function getOAuth2Service()
+ {
+ if (!isset($this->auth)) {
+ $this->auth = $this->createOAuth2Service();
+ }
+ return $this->auth;
+ }
+ /**
+ * create a default google auth object
+ */
+ protected function createOAuth2Service()
+ {
+ $auth = new OAuth2(['clientId' => $this->getClientId(), 'clientSecret' => $this->getClientSecret(), 'authorizationUri' => self::OAUTH2_AUTH_URL, 'tokenCredentialUri' => self::OAUTH2_TOKEN_URI, 'redirectUri' => $this->getRedirectUri(), 'issuer' => $this->config['client_id'], 'signingKey' => $this->config['signing_key'], 'signingAlgorithm' => $this->config['signing_algorithm']]);
+ return $auth;
+ }
+ /**
+ * Set the Cache object
+ * @param CacheItemPoolInterface $cache
+ */
+ public function setCache(CacheItemPoolInterface $cache)
+ {
+ $this->cache = $cache;
+ }
+ /**
+ * @return CacheItemPoolInterface
+ */
+ public function getCache()
+ {
+ if (!$this->cache) {
+ $this->cache = $this->createDefaultCache();
+ }
+ return $this->cache;
+ }
+ /**
+ * @param array $cacheConfig
+ */
+ public function setCacheConfig(array $cacheConfig)
+ {
+ $this->config['cache_config'] = $cacheConfig;
+ }
+ /**
+ * Set the Logger object
+ * @param LoggerInterface $logger
+ */
+ public function setLogger(LoggerInterface $logger)
+ {
+ $this->logger = $logger;
+ }
+ /**
+ * @return LoggerInterface
+ */
+ public function getLogger()
+ {
+ if (!isset($this->logger)) {
+ $this->logger = $this->createDefaultLogger();
+ }
+ return $this->logger;
+ }
+ protected function createDefaultLogger()
+ {
+ $logger = new Logger('google-api-php-client');
+ if ($this->isAppEngine()) {
+ $handler = new MonologSyslogHandler('app', \LOG_USER, Logger::NOTICE);
+ } else {
+ $handler = new MonologStreamHandler('php://stderr', Logger::NOTICE);
+ }
+ $logger->pushHandler($handler);
+ return $logger;
+ }
+ protected function createDefaultCache()
+ {
+ return new MemoryCacheItemPool();
+ }
+ /**
+ * Set the Http Client object
+ * @param ClientInterface $http
+ */
+ public function setHttpClient(ClientInterface $http)
+ {
+ $this->http = $http;
+ }
+ /**
+ * @return ClientInterface
+ */
+ public function getHttpClient()
+ {
+ if (null === $this->http) {
+ $this->http = $this->createDefaultHttpClient();
+ }
+ return $this->http;
+ }
+ /**
+ * Set the API format version.
+ *
+ * `true` will use V2, which may return more useful error messages.
+ *
+ * @param bool $value
+ */
+ public function setApiFormatV2($value)
+ {
+ $this->config['api_format_v2'] = (bool) $value;
+ }
+ protected function createDefaultHttpClient()
+ {
+ $guzzleVersion = null;
+ if (\defined('\\WPMailSMTP\\Vendor\\GuzzleHttp\\ClientInterface::MAJOR_VERSION')) {
+ $guzzleVersion = ClientInterface::MAJOR_VERSION;
+ } elseif (\defined('\\WPMailSMTP\\Vendor\\GuzzleHttp\\ClientInterface::VERSION')) {
+ $guzzleVersion = (int) \substr(ClientInterface::VERSION, 0, 1);
+ }
+ if (5 === $guzzleVersion) {
+ $options = ['base_url' => $this->config['base_path'], 'defaults' => ['exceptions' => \false]];
+ if ($this->isAppEngine()) {
+ if (\class_exists(StreamHandler::class)) {
+ // set StreamHandler on AppEngine by default
+ $options['handler'] = new StreamHandler();
+ $options['defaults']['verify'] = '/etc/ca-certificates.crt';
+ }
+ }
+ } elseif (6 === $guzzleVersion || 7 === $guzzleVersion) {
+ // guzzle 6 or 7
+ $options = ['base_uri' => $this->config['base_path'], 'http_errors' => \false];
+ } else {
+ throw new LogicException('Could not find supported version of Guzzle.');
+ }
+ return new GuzzleClient($options);
+ }
+ /**
+ * @return FetchAuthTokenCache
+ */
+ private function createApplicationDefaultCredentials()
+ {
+ $scopes = $this->prepareScopes();
+ $sub = $this->config['subject'];
+ $signingKey = $this->config['signing_key'];
+ // create credentials using values supplied in setAuthConfig
+ if ($signingKey) {
+ $serviceAccountCredentials = ['client_id' => $this->config['client_id'], 'client_email' => $this->config['client_email'], 'private_key' => $signingKey, 'type' => 'service_account', 'quota_project_id' => $this->config['quota_project']];
+ $credentials = CredentialsLoader::makeCredentials($scopes, $serviceAccountCredentials);
+ } else {
+ // When $sub is provided, we cannot pass cache classes to ::getCredentials
+ // because FetchAuthTokenCache::setSub does not exist.
+ // The result is when $sub is provided, calls to ::onGce are not cached.
+ $credentials = ApplicationDefaultCredentials::getCredentials($scopes, null, $sub ? null : $this->config['cache_config'], $sub ? null : $this->getCache(), $this->config['quota_project']);
+ }
+ // for service account domain-wide authority (impersonating a user)
+ // @see https://developers.google.com/identity/protocols/OAuth2ServiceAccount
+ if ($sub) {
+ if (!$credentials instanceof ServiceAccountCredentials) {
+ throw new DomainException('domain-wide authority requires service account credentials');
+ }
+ $credentials->setSub($sub);
+ }
+ // If we are not using FetchAuthTokenCache yet, create it now
+ if (!$credentials instanceof FetchAuthTokenCache) {
+ $credentials = new FetchAuthTokenCache($credentials, $this->config['cache_config'], $this->getCache());
+ }
+ return $credentials;
+ }
+ protected function getAuthHandler()
+ {
+ // Be very careful using the cache, as the underlying auth library's cache
+ // implementation is naive, and the cache keys do not account for user
+ // sessions.
+ //
+ // @see https://github.com/google/google-api-php-client/issues/821
+ return AuthHandlerFactory::build($this->getCache(), $this->config['cache_config']);
+ }
+ private function createUserRefreshCredentials($scope, $refreshToken)
+ {
+ $creds = \array_filter(['client_id' => $this->getClientId(), 'client_secret' => $this->getClientSecret(), 'refresh_token' => $refreshToken]);
+ return new UserRefreshCredentials($scope, $creds);
+ }
+ private function checkUniverseDomain($credentials)
+ {
+ $credentialsUniverse = $credentials instanceof GetUniverseDomainInterface ? $credentials->getUniverseDomain() : GetUniverseDomainInterface::DEFAULT_UNIVERSE_DOMAIN;
+ if ($credentialsUniverse !== $this->getUniverseDomain()) {
+ throw new DomainException(\sprintf('The configured universe domain (%s) does not match the credential universe domain (%s)', $this->getUniverseDomain(), $credentialsUniverse));
+ }
+ }
+ public function getUniverseDomain()
+ {
+ return $this->config['universe_domain'];
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/Collection.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/Collection.php
new file mode 100755
index 00000000..860b1f5b
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/Collection.php
@@ -0,0 +1,104 @@
+{$this->collection_key}) && \is_array($this->{$this->collection_key})) {
+ \reset($this->{$this->collection_key});
+ }
+ }
+ /** @return mixed */
+ #[\ReturnTypeWillChange]
+ public function current()
+ {
+ $this->coerceType($this->key());
+ if (\is_array($this->{$this->collection_key})) {
+ return \current($this->{$this->collection_key});
+ }
+ }
+ /** @return mixed */
+ #[\ReturnTypeWillChange]
+ public function key()
+ {
+ if (isset($this->{$this->collection_key}) && \is_array($this->{$this->collection_key})) {
+ return \key($this->{$this->collection_key});
+ }
+ }
+ /** @return mixed */
+ #[\ReturnTypeWillChange]
+ public function next()
+ {
+ return \next($this->{$this->collection_key});
+ }
+ /** @return bool */
+ #[\ReturnTypeWillChange]
+ public function valid()
+ {
+ $key = $this->key();
+ return $key !== null && $key !== \false;
+ }
+ /** @return int */
+ #[\ReturnTypeWillChange]
+ public function count()
+ {
+ if (!isset($this->{$this->collection_key})) {
+ return 0;
+ }
+ return \count($this->{$this->collection_key});
+ }
+ /** @return bool */
+ #[\ReturnTypeWillChange]
+ public function offsetExists($offset)
+ {
+ if (!\is_numeric($offset)) {
+ return parent::offsetExists($offset);
+ }
+ return isset($this->{$this->collection_key}[$offset]);
+ }
+ /** @return mixed */
+ #[\ReturnTypeWillChange]
+ public function offsetGet($offset)
+ {
+ if (!\is_numeric($offset)) {
+ return parent::offsetGet($offset);
+ }
+ $this->coerceType($offset);
+ return $this->{$this->collection_key}[$offset];
+ }
+ /** @return void */
+ #[\ReturnTypeWillChange]
+ public function offsetSet($offset, $value)
+ {
+ if (!\is_numeric($offset)) {
+ parent::offsetSet($offset, $value);
+ }
+ $this->{$this->collection_key}[$offset] = $value;
+ }
+ /** @return void */
+ #[\ReturnTypeWillChange]
+ public function offsetUnset($offset)
+ {
+ if (!\is_numeric($offset)) {
+ parent::offsetUnset($offset);
+ }
+ unset($this->{$this->collection_key}[$offset]);
+ }
+ private function coerceType($offset)
+ {
+ $keyType = $this->keyType($this->collection_key);
+ if ($keyType && !\is_object($this->{$this->collection_key}[$offset])) {
+ $this->{$this->collection_key}[$offset] = new $keyType($this->{$this->collection_key}[$offset]);
+ }
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/Exception.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/Exception.php
new file mode 100755
index 00000000..923c54e8
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/Exception.php
@@ -0,0 +1,23 @@
+client = $client;
+ $this->boundary = $boundary ?: \mt_rand();
+ $rootUrl = \rtrim($rootUrl ?: $this->client->getConfig('base_path'), '/');
+ $this->rootUrl = \str_replace('UNIVERSE_DOMAIN', $this->client->getUniverseDomain(), $rootUrl);
+ $this->batchPath = $batchPath ?: self::BATCH_PATH;
+ }
+ public function add(RequestInterface $request, $key = \false)
+ {
+ if (\false == $key) {
+ $key = \mt_rand();
+ }
+ $this->requests[$key] = $request;
+ }
+ public function execute()
+ {
+ $body = '';
+ $classes = [];
+ $batchHttpTemplate = <<requests as $key => $request) {
+ $firstLine = \sprintf('%s %s HTTP/%s', $request->getMethod(), $request->getRequestTarget(), $request->getProtocolVersion());
+ $content = (string) $request->getBody();
+ $headers = '';
+ foreach ($request->getHeaders() as $name => $values) {
+ $headers .= \sprintf("%s:%s\r\n", $name, \implode(', ', $values));
+ }
+ $body .= \sprintf($batchHttpTemplate, $this->boundary, $key, $firstLine, $headers, $content ? "\n" . $content : '');
+ $classes['response-' . $key] = $request->getHeaderLine('X-Php-Expected-Class');
+ }
+ $body .= "--{$this->boundary}--";
+ $body = \trim($body);
+ $url = $this->rootUrl . '/' . $this->batchPath;
+ $headers = ['Content-Type' => \sprintf('multipart/mixed; boundary=%s', $this->boundary), 'Content-Length' => (string) \strlen($body)];
+ $request = new Request('POST', $url, $headers, $body);
+ $response = $this->client->execute($request);
+ return $this->parseResponse($response, $classes);
+ }
+ public function parseResponse(ResponseInterface $response, $classes = [])
+ {
+ $contentType = $response->getHeaderLine('content-type');
+ $contentType = \explode(';', $contentType);
+ $boundary = \false;
+ foreach ($contentType as $part) {
+ $part = \explode('=', $part, 2);
+ if (isset($part[0]) && 'boundary' == \trim($part[0])) {
+ $boundary = $part[1];
+ }
+ }
+ $body = (string) $response->getBody();
+ if (!empty($body)) {
+ $body = \str_replace("--{$boundary}--", "--{$boundary}", $body);
+ $parts = \explode("--{$boundary}", $body);
+ $responses = [];
+ $requests = \array_values($this->requests);
+ foreach ($parts as $i => $part) {
+ $part = \trim($part);
+ if (!empty($part)) {
+ list($rawHeaders, $part) = \explode("\r\n\r\n", $part, 2);
+ $headers = $this->parseRawHeaders($rawHeaders);
+ $status = \substr($part, 0, \strpos($part, "\n"));
+ $status = \explode(" ", $status);
+ $status = $status[1];
+ list($partHeaders, $partBody) = $this->parseHttpResponse($part, 0);
+ $response = new Response((int) $status, $partHeaders, Psr7\Utils::streamFor($partBody));
+ // Need content id.
+ $key = $headers['content-id'];
+ try {
+ $response = REST::decodeHttpResponse($response, $requests[$i - 1]);
+ } catch (GoogleServiceException $e) {
+ // Store the exception as the response, so successful responses
+ // can be processed.
+ $response = $e;
+ }
+ $responses[$key] = $response;
+ }
+ }
+ return $responses;
+ }
+ return null;
+ }
+ private function parseRawHeaders($rawHeaders)
+ {
+ $headers = [];
+ $responseHeaderLines = \explode("\r\n", $rawHeaders);
+ foreach ($responseHeaderLines as $headerLine) {
+ if ($headerLine && \strpos($headerLine, ':') !== \false) {
+ list($header, $value) = \explode(': ', $headerLine, 2);
+ $header = \strtolower($header);
+ if (isset($headers[$header])) {
+ $headers[$header] = \array_merge((array) $headers[$header], (array) $value);
+ } else {
+ $headers[$header] = $value;
+ }
+ }
+ }
+ return $headers;
+ }
+ /**
+ * Used by the IO lib and also the batch processing.
+ *
+ * @param string $respData
+ * @param int $headerSize
+ * @return array
+ */
+ private function parseHttpResponse($respData, $headerSize)
+ {
+ // check proxy header
+ foreach (self::$CONNECTION_ESTABLISHED_HEADERS as $established_header) {
+ if (\stripos($respData, $established_header) !== \false) {
+ // existed, remove it
+ $respData = \str_ireplace($established_header, '', $respData);
+ // Subtract the proxy header size unless the cURL bug prior to 7.30.0
+ // is present which prevented the proxy header size from being taken into
+ // account.
+ // @TODO look into this
+ // if (!$this->needsQuirk()) {
+ // $headerSize -= strlen($established_header);
+ // }
+ break;
+ }
+ }
+ if ($headerSize) {
+ $responseBody = \substr($respData, $headerSize);
+ $responseHeaders = \substr($respData, 0, $headerSize);
+ } else {
+ $responseSegments = \explode("\r\n\r\n", $respData, 2);
+ $responseHeaders = $responseSegments[0];
+ $responseBody = isset($responseSegments[1]) ? $responseSegments[1] : null;
+ }
+ $responseHeaders = $this->parseRawHeaders($responseHeaders);
+ return [$responseHeaders, $responseBody];
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/Http/MediaFileUpload.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/Http/MediaFileUpload.php
new file mode 100755
index 00000000..7e5c3ff1
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/Http/MediaFileUpload.php
@@ -0,0 +1,273 @@
+client = $client;
+ $this->request = $request;
+ $this->mimeType = $mimeType;
+ $this->data = $data;
+ $this->resumable = $resumable;
+ $this->chunkSize = $chunkSize;
+ $this->progress = 0;
+ $this->process();
+ }
+ /**
+ * Set the size of the file that is being uploaded.
+ * @param int $size - int file size in bytes
+ */
+ public function setFileSize($size)
+ {
+ $this->size = $size;
+ }
+ /**
+ * Return the progress on the upload
+ * @return int progress in bytes uploaded.
+ */
+ public function getProgress()
+ {
+ return $this->progress;
+ }
+ /**
+ * Send the next part of the file to upload.
+ * @param string|bool $chunk Optional. The next set of bytes to send. If false will
+ * use $data passed at construct time.
+ */
+ public function nextChunk($chunk = \false)
+ {
+ $resumeUri = $this->getResumeUri();
+ if (\false == $chunk) {
+ $chunk = \substr($this->data, $this->progress, $this->chunkSize);
+ }
+ $lastBytePos = $this->progress + \strlen($chunk) - 1;
+ $headers = ['content-range' => "bytes {$this->progress}-{$lastBytePos}/{$this->size}", 'content-length' => (string) \strlen($chunk), 'expect' => ''];
+ $request = new Request('PUT', $resumeUri, $headers, Psr7\Utils::streamFor($chunk));
+ return $this->makePutRequest($request);
+ }
+ /**
+ * Return the HTTP result code from the last call made.
+ * @return int code
+ */
+ public function getHttpResultCode()
+ {
+ return $this->httpResultCode;
+ }
+ /**
+ * Sends a PUT-Request to google drive and parses the response,
+ * setting the appropiate variables from the response()
+ *
+ * @param RequestInterface $request the Request which will be send
+ *
+ * @return false|mixed false when the upload is unfinished or the decoded http response
+ *
+ */
+ private function makePutRequest(RequestInterface $request)
+ {
+ $response = $this->client->execute($request);
+ $this->httpResultCode = $response->getStatusCode();
+ if (308 == $this->httpResultCode) {
+ // Track the amount uploaded.
+ $range = $response->getHeaderLine('range');
+ if ($range) {
+ $range_array = \explode('-', $range);
+ $this->progress = (int) $range_array[1] + 1;
+ }
+ // Allow for changing upload URLs.
+ $location = $response->getHeaderLine('location');
+ if ($location) {
+ $this->resumeUri = $location;
+ }
+ // No problems, but upload not complete.
+ return \false;
+ }
+ return REST::decodeHttpResponse($response, $this->request);
+ }
+ /**
+ * Resume a previously unfinished upload
+ * @param string $resumeUri the resume-URI of the unfinished, resumable upload.
+ */
+ public function resume($resumeUri)
+ {
+ $this->resumeUri = $resumeUri;
+ $headers = ['content-range' => "bytes */{$this->size}", 'content-length' => '0'];
+ $httpRequest = new Request('PUT', $this->resumeUri, $headers);
+ return $this->makePutRequest($httpRequest);
+ }
+ /**
+ * @return RequestInterface
+ * @visible for testing
+ */
+ private function process()
+ {
+ $this->transformToUploadUrl();
+ $request = $this->request;
+ $postBody = '';
+ $contentType = \false;
+ $meta = \json_decode((string) $request->getBody(), \true);
+ $uploadType = $this->getUploadType($meta);
+ $request = $request->withUri(Uri::withQueryValue($request->getUri(), 'uploadType', $uploadType));
+ $mimeType = $this->mimeType ?: $request->getHeaderLine('content-type');
+ if (self::UPLOAD_RESUMABLE_TYPE == $uploadType) {
+ $contentType = $mimeType;
+ $postBody = \is_string($meta) ? $meta : \json_encode($meta);
+ } elseif (self::UPLOAD_MEDIA_TYPE == $uploadType) {
+ $contentType = $mimeType;
+ $postBody = $this->data;
+ } elseif (self::UPLOAD_MULTIPART_TYPE == $uploadType) {
+ // This is a multipart/related upload.
+ $boundary = $this->boundary ?: \mt_rand();
+ $boundary = \str_replace('"', '', $boundary);
+ $contentType = 'multipart/related; boundary=' . $boundary;
+ $related = "--{$boundary}\r\n";
+ $related .= "Content-Type: application/json; charset=UTF-8\r\n";
+ $related .= "\r\n" . \json_encode($meta) . "\r\n";
+ $related .= "--{$boundary}\r\n";
+ $related .= "Content-Type: {$mimeType}\r\n";
+ $related .= "Content-Transfer-Encoding: base64\r\n";
+ $related .= "\r\n" . \base64_encode($this->data) . "\r\n";
+ $related .= "--{$boundary}--";
+ $postBody = $related;
+ }
+ $request = $request->withBody(Psr7\Utils::streamFor($postBody));
+ if ($contentType) {
+ $request = $request->withHeader('content-type', $contentType);
+ }
+ return $this->request = $request;
+ }
+ /**
+ * Valid upload types:
+ * - resumable (UPLOAD_RESUMABLE_TYPE)
+ * - media (UPLOAD_MEDIA_TYPE)
+ * - multipart (UPLOAD_MULTIPART_TYPE)
+ * @param string|false $meta
+ * @return string
+ * @visible for testing
+ */
+ public function getUploadType($meta)
+ {
+ if ($this->resumable) {
+ return self::UPLOAD_RESUMABLE_TYPE;
+ }
+ if (\false == $meta && $this->data) {
+ return self::UPLOAD_MEDIA_TYPE;
+ }
+ return self::UPLOAD_MULTIPART_TYPE;
+ }
+ public function getResumeUri()
+ {
+ if (null === $this->resumeUri) {
+ $this->resumeUri = $this->fetchResumeUri();
+ }
+ return $this->resumeUri;
+ }
+ private function fetchResumeUri()
+ {
+ $body = $this->request->getBody();
+ $headers = ['content-type' => 'application/json; charset=UTF-8', 'content-length' => $body->getSize(), 'x-upload-content-type' => $this->mimeType, 'x-upload-content-length' => $this->size, 'expect' => ''];
+ foreach ($headers as $key => $value) {
+ $this->request = $this->request->withHeader($key, $value);
+ }
+ $response = $this->client->execute($this->request, \false);
+ $location = $response->getHeaderLine('location');
+ $code = $response->getStatusCode();
+ if (200 == $code && \true == $location) {
+ return $location;
+ }
+ $message = $code;
+ $body = \json_decode((string) $this->request->getBody(), \true);
+ if (isset($body['error']['errors'])) {
+ $message .= ': ';
+ foreach ($body['error']['errors'] as $error) {
+ $message .= "{$error['domain']}, {$error['message']};";
+ }
+ $message = \rtrim($message, ';');
+ }
+ $error = "Failed to start the resumable upload (HTTP {$message})";
+ $this->client->getLogger()->error($error);
+ throw new GoogleException($error);
+ }
+ private function transformToUploadUrl()
+ {
+ $parts = \parse_url((string) $this->request->getUri());
+ if (!isset($parts['path'])) {
+ $parts['path'] = '';
+ }
+ $parts['path'] = '/upload' . $parts['path'];
+ $uri = Uri::fromParts($parts);
+ $this->request = $this->request->withUri($uri);
+ }
+ public function setChunkSize($chunkSize)
+ {
+ $this->chunkSize = $chunkSize;
+ }
+ public function getRequest()
+ {
+ return $this->request;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/Http/REST.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/Http/REST.php
new file mode 100755
index 00000000..696f00be
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/Http/REST.php
@@ -0,0 +1,153 @@
+|false|null $expectedClass
+ * @param array $config
+ * @param array $retryMap
+ * @return mixed|T|null
+ * @throws \Google\Service\Exception on server side error (ie: not authenticated,
+ * invalid or malformed post body, invalid url)
+ */
+ public static function execute(ClientInterface $client, RequestInterface $request, $expectedClass = null, $config = [], $retryMap = null)
+ {
+ $runner = new Runner($config, \sprintf('%s %s', $request->getMethod(), (string) $request->getUri()), [self::class, 'doExecute'], [$client, $request, $expectedClass]);
+ if (null !== $retryMap) {
+ $runner->setRetryMap($retryMap);
+ }
+ return $runner->run();
+ }
+ /**
+ * Executes a Psr\Http\Message\RequestInterface
+ *
+ * @template T
+ * @param ClientInterface $client
+ * @param RequestInterface $request
+ * @param class-string|false|null $expectedClass
+ * @return mixed|T|null
+ * @throws \Google\Service\Exception on server side error (ie: not authenticated,
+ * invalid or malformed post body, invalid url)
+ */
+ public static function doExecute(ClientInterface $client, RequestInterface $request, $expectedClass = null)
+ {
+ try {
+ $httpHandler = HttpHandlerFactory::build($client);
+ $response = $httpHandler($request);
+ } catch (RequestException $e) {
+ // if Guzzle throws an exception, catch it and handle the response
+ if (!$e->hasResponse()) {
+ throw $e;
+ }
+ $response = $e->getResponse();
+ // specific checking for Guzzle 5: convert to PSR7 response
+ if (\interface_exists('WPMailSMTP\\Vendor\\GuzzleHttp\\Message\\ResponseInterface') && $response instanceof \WPMailSMTP\Vendor\GuzzleHttp\Message\ResponseInterface) {
+ $response = new Response($response->getStatusCode(), $response->getHeaders() ?: [], $response->getBody(), $response->getProtocolVersion(), $response->getReasonPhrase());
+ }
+ }
+ return self::decodeHttpResponse($response, $request, $expectedClass);
+ }
+ /**
+ * Decode an HTTP Response.
+ * @static
+ *
+ * @template T
+ * @param RequestInterface $response The http response to be decoded.
+ * @param ResponseInterface $response
+ * @param class-string|false|null $expectedClass
+ * @return mixed|T|null
+ * @throws \Google\Service\Exception
+ */
+ public static function decodeHttpResponse(ResponseInterface $response, ?RequestInterface $request = null, $expectedClass = null)
+ {
+ $code = $response->getStatusCode();
+ // retry strategy
+ if (\intVal($code) >= 400) {
+ // if we errored out, it should be safe to grab the response body
+ $body = (string) $response->getBody();
+ // Check if we received errors, and add those to the Exception for convenience
+ throw new GoogleServiceException($body, $code, null, self::getResponseErrors($body));
+ }
+ // Ensure we only pull the entire body into memory if the request is not
+ // of media type
+ $body = self::decodeBody($response, $request);
+ if ($expectedClass = self::determineExpectedClass($expectedClass, $request)) {
+ $json = \json_decode($body, \true);
+ return new $expectedClass($json);
+ }
+ return $response;
+ }
+ private static function decodeBody(ResponseInterface $response, ?RequestInterface $request = null)
+ {
+ if (self::isAltMedia($request)) {
+ // don't decode the body, it's probably a really long string
+ return '';
+ }
+ return (string) $response->getBody();
+ }
+ private static function determineExpectedClass($expectedClass, ?RequestInterface $request = null)
+ {
+ // "false" is used to explicitly prevent an expected class from being returned
+ if (\false === $expectedClass) {
+ return null;
+ }
+ // if we don't have a request, we just use what's passed in
+ if (null === $request) {
+ return $expectedClass;
+ }
+ // return what we have in the request header if one was not supplied
+ return $expectedClass ?: $request->getHeaderLine('X-Php-Expected-Class');
+ }
+ private static function getResponseErrors($body)
+ {
+ $json = \json_decode($body, \true);
+ if (isset($json['error']['errors'])) {
+ return $json['error']['errors'];
+ }
+ return null;
+ }
+ private static function isAltMedia(?RequestInterface $request = null)
+ {
+ if ($request && ($qs = $request->getUri()->getQuery())) {
+ \parse_str($qs, $query);
+ if (isset($query['alt']) && $query['alt'] == 'media') {
+ return \true;
+ }
+ }
+ return \false;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/Model.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/Model.php
new file mode 100755
index 00000000..66d31ac1
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/Model.php
@@ -0,0 +1,301 @@
+mapTypes($array);
+ }
+ $this->gapiInit();
+ }
+ /**
+ * Getter that handles passthrough access to the data array, and lazy object creation.
+ * @param string $key Property name.
+ * @return mixed The value if any, or null.
+ */
+ public function __get($key)
+ {
+ $keyType = $this->keyType($key);
+ $keyDataType = $this->dataType($key);
+ if ($keyType && !isset($this->processed[$key])) {
+ if (isset($this->modelData[$key])) {
+ $val = $this->modelData[$key];
+ } elseif ($keyDataType == 'array' || $keyDataType == 'map') {
+ $val = [];
+ } else {
+ $val = null;
+ }
+ if ($this->isAssociativeArray($val)) {
+ if ($keyDataType && 'map' == $keyDataType) {
+ foreach ($val as $arrayKey => $arrayItem) {
+ $this->modelData[$key][$arrayKey] = new $keyType($arrayItem);
+ }
+ } else {
+ $this->modelData[$key] = new $keyType($val);
+ }
+ } elseif (\is_array($val)) {
+ $arrayObject = [];
+ foreach ($val as $arrayIndex => $arrayItem) {
+ $arrayObject[$arrayIndex] = new $keyType($arrayItem);
+ }
+ $this->modelData[$key] = $arrayObject;
+ }
+ $this->processed[$key] = \true;
+ }
+ return isset($this->modelData[$key]) ? $this->modelData[$key] : null;
+ }
+ /**
+ * Initialize this object's properties from an array.
+ *
+ * @param array $array Used to seed this object's properties.
+ * @return void
+ */
+ protected function mapTypes($array)
+ {
+ // Hard initialise simple types, lazy load more complex ones.
+ foreach ($array as $key => $val) {
+ if ($keyType = $this->keyType($key)) {
+ $dataType = $this->dataType($key);
+ if ($dataType == 'array' || $dataType == 'map') {
+ $this->{$key} = [];
+ foreach ($val as $itemKey => $itemVal) {
+ if ($itemVal instanceof $keyType) {
+ $this->{$key}[$itemKey] = $itemVal;
+ } else {
+ $this->{$key}[$itemKey] = new $keyType($itemVal);
+ }
+ }
+ } elseif ($val instanceof $keyType) {
+ $this->{$key} = $val;
+ } else {
+ $this->{$key} = new $keyType($val);
+ }
+ unset($array[$key]);
+ } elseif (\property_exists($this, $key)) {
+ $this->{$key} = $val;
+ unset($array[$key]);
+ } elseif (\property_exists($this, $camelKey = $this->camelCase($key))) {
+ // This checks if property exists as camelCase, leaving it in array as snake_case
+ // in case of backwards compatibility issues.
+ $this->{$camelKey} = $val;
+ }
+ }
+ $this->modelData = $array;
+ }
+ /**
+ * Blank initialiser to be used in subclasses to do post-construction initialisation - this
+ * avoids the need for subclasses to have to implement the variadics handling in their
+ * constructors.
+ */
+ protected function gapiInit()
+ {
+ return;
+ }
+ /**
+ * Create a simplified object suitable for straightforward
+ * conversion to JSON. This is relatively expensive
+ * due to the usage of reflection, but shouldn't be called
+ * a whole lot, and is the most straightforward way to filter.
+ */
+ public function toSimpleObject()
+ {
+ $object = new stdClass();
+ // Process all other data.
+ foreach ($this->modelData as $key => $val) {
+ $result = $this->getSimpleValue($val);
+ if ($result !== null) {
+ $object->{$key} = $this->nullPlaceholderCheck($result);
+ }
+ }
+ // Process all public properties.
+ $reflect = new ReflectionObject($this);
+ $props = $reflect->getProperties(ReflectionProperty::IS_PUBLIC);
+ foreach ($props as $member) {
+ $name = $member->getName();
+ $result = $this->getSimpleValue($this->{$name});
+ if ($result !== null) {
+ $name = $this->getMappedName($name);
+ $object->{$name} = $this->nullPlaceholderCheck($result);
+ }
+ }
+ return $object;
+ }
+ /**
+ * Handle different types of values, primarily
+ * other objects and map and array data types.
+ */
+ private function getSimpleValue($value)
+ {
+ if ($value instanceof Model) {
+ return $value->toSimpleObject();
+ } elseif (\is_array($value)) {
+ $return = [];
+ foreach ($value as $key => $a_value) {
+ $a_value = $this->getSimpleValue($a_value);
+ if ($a_value !== null) {
+ $key = $this->getMappedName($key);
+ $return[$key] = $this->nullPlaceholderCheck($a_value);
+ }
+ }
+ return $return;
+ }
+ return $value;
+ }
+ /**
+ * Check whether the value is the null placeholder and return true null.
+ */
+ private function nullPlaceholderCheck($value)
+ {
+ if ($value === self::NULL_VALUE) {
+ return null;
+ }
+ return $value;
+ }
+ /**
+ * If there is an internal name mapping, use that.
+ */
+ private function getMappedName($key)
+ {
+ if (isset($this->internal_gapi_mappings, $this->internal_gapi_mappings[$key])) {
+ $key = $this->internal_gapi_mappings[$key];
+ }
+ return $key;
+ }
+ /**
+ * Returns true only if the array is associative.
+ * @param array $array
+ * @return bool True if the array is associative.
+ */
+ protected function isAssociativeArray($array)
+ {
+ if (!\is_array($array)) {
+ return \false;
+ }
+ $keys = \array_keys($array);
+ foreach ($keys as $key) {
+ if (\is_string($key)) {
+ return \true;
+ }
+ }
+ return \false;
+ }
+ /**
+ * Verify if $obj is an array.
+ * @throws \Google\Exception Thrown if $obj isn't an array.
+ * @param array $obj Items that should be validated.
+ * @param string $method Method expecting an array as an argument.
+ */
+ public function assertIsArray($obj, $method)
+ {
+ if ($obj && !\is_array($obj)) {
+ throw new GoogleException("Incorrect parameter type passed to {$method}(). Expected an array.");
+ }
+ }
+ /** @return bool */
+ #[\ReturnTypeWillChange]
+ public function offsetExists($offset)
+ {
+ return isset($this->{$offset}) || isset($this->modelData[$offset]);
+ }
+ /** @return mixed */
+ #[\ReturnTypeWillChange]
+ public function offsetGet($offset)
+ {
+ return isset($this->{$offset}) ? $this->{$offset} : $this->__get($offset);
+ }
+ /** @return void */
+ #[\ReturnTypeWillChange]
+ public function offsetSet($offset, $value)
+ {
+ if (\property_exists($this, $offset)) {
+ $this->{$offset} = $value;
+ } else {
+ $this->modelData[$offset] = $value;
+ $this->processed[$offset] = \true;
+ }
+ }
+ /** @return void */
+ #[\ReturnTypeWillChange]
+ public function offsetUnset($offset)
+ {
+ unset($this->modelData[$offset]);
+ }
+ protected function keyType($key)
+ {
+ $keyType = $key . "Type";
+ // ensure keyType is a valid class
+ if (\property_exists($this, $keyType) && $this->{$keyType} !== null && \class_exists($this->{$keyType})) {
+ return $this->{$keyType};
+ }
+ }
+ protected function dataType($key)
+ {
+ $dataType = $key . "DataType";
+ if (\property_exists($this, $dataType)) {
+ return $this->{$dataType};
+ }
+ }
+ public function __isset($key)
+ {
+ return isset($this->modelData[$key]);
+ }
+ public function __unset($key)
+ {
+ unset($this->modelData[$key]);
+ }
+ /**
+ * Convert a string to camelCase
+ * @param string $value
+ * @return string
+ */
+ private function camelCase($value)
+ {
+ $value = \ucwords(\str_replace(['-', '_'], ' ', $value));
+ $value = \str_replace(' ', '', $value);
+ $value[0] = \strtolower($value[0]);
+ return $value;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/Service.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/Service.php
new file mode 100755
index 00000000..1dc2bc21
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/Service.php
@@ -0,0 +1,67 @@
+client = $clientOrConfig;
+ } elseif (\is_array($clientOrConfig)) {
+ $this->client = new Client($clientOrConfig ?: []);
+ } else {
+ $errorMessage = 'WPMailSMTP\\Vendor\\constructor must be array or instance of Google\\Client';
+ if (\class_exists('TypeError')) {
+ throw new TypeError($errorMessage);
+ }
+ \trigger_error($errorMessage, \E_USER_ERROR);
+ }
+ }
+ /**
+ * Return the associated Google\Client class.
+ * @return \Google\Client
+ */
+ public function getClient()
+ {
+ return $this->client;
+ }
+ /**
+ * Create a new HTTP Batch handler for this service
+ *
+ * @return Batch
+ */
+ public function createBatch()
+ {
+ return new Batch($this->client, \false, $this->rootUrlTemplate ?? $this->rootUrl, $this->batchPath);
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/Service/Exception.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/Service/Exception.php
new file mode 100755
index 00000000..b3f6dd89
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/Service/Exception.php
@@ -0,0 +1,65 @@
+>|null $errors List of errors returned in an HTTP
+ * response or null. Defaults to [].
+ */
+ public function __construct($message, $code = 0, ?Exception $previous = null, $errors = [])
+ {
+ if (\version_compare(\PHP_VERSION, '5.3.0') >= 0) {
+ parent::__construct($message, $code, $previous);
+ } else {
+ parent::__construct($message, $code);
+ }
+ $this->errors = $errors;
+ }
+ /**
+ * An example of the possible errors returned.
+ *
+ * [
+ * {
+ * "domain": "global",
+ * "reason": "authError",
+ * "message": "Invalid Credentials",
+ * "locationType": "header",
+ * "location": "Authorization",
+ * }
+ * ]
+ *
+ * @return array>|null List of errors returned in an HTTP response or null.
+ */
+ public function getErrors()
+ {
+ return $this->errors;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/Service/Resource.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/Service/Resource.php
new file mode 100755
index 00000000..42a5899b
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/Service/Resource.php
@@ -0,0 +1,216 @@
+ ['type' => 'string', 'location' => 'query'], 'fields' => ['type' => 'string', 'location' => 'query'], 'trace' => ['type' => 'string', 'location' => 'query'], 'userIp' => ['type' => 'string', 'location' => 'query'], 'quotaUser' => ['type' => 'string', 'location' => 'query'], 'data' => ['type' => 'string', 'location' => 'body'], 'mimeType' => ['type' => 'string', 'location' => 'header'], 'uploadType' => ['type' => 'string', 'location' => 'query'], 'mediaUpload' => ['type' => 'complex', 'location' => 'query'], 'prettyPrint' => ['type' => 'string', 'location' => 'query']];
+ /** @var string $rootUrlTemplate */
+ private $rootUrlTemplate;
+ /** @var \Google\Client $client */
+ private $client;
+ /** @var string $serviceName */
+ private $serviceName;
+ /** @var string $servicePath */
+ private $servicePath;
+ /** @var string $resourceName */
+ private $resourceName;
+ /** @var array $methods */
+ private $methods;
+ public function __construct($service, $serviceName, $resourceName, $resource)
+ {
+ $this->rootUrlTemplate = $service->rootUrlTemplate ?? $service->rootUrl;
+ $this->client = $service->getClient();
+ $this->servicePath = $service->servicePath;
+ $this->serviceName = $serviceName;
+ $this->resourceName = $resourceName;
+ $this->methods = \is_array($resource) && isset($resource['methods']) ? $resource['methods'] : [$resourceName => $resource];
+ }
+ /**
+ * TODO: This function needs simplifying.
+ *
+ * @template T
+ * @param string $name
+ * @param array $arguments
+ * @param class-string $expectedClass - optional, the expected class name
+ * @return mixed|T|ResponseInterface|RequestInterface
+ * @throws \Google\Exception
+ */
+ public function call($name, $arguments, $expectedClass = null)
+ {
+ if (!isset($this->methods[$name])) {
+ $this->client->getLogger()->error('Service method unknown', ['service' => $this->serviceName, 'resource' => $this->resourceName, 'method' => $name]);
+ throw new GoogleException("Unknown function: " . "{$this->serviceName}->{$this->resourceName}->{$name}()");
+ }
+ $method = $this->methods[$name];
+ $parameters = $arguments[0];
+ // postBody is a special case since it's not defined in the discovery
+ // document as parameter, but we abuse the param entry for storing it.
+ $postBody = null;
+ if (isset($parameters['postBody'])) {
+ if ($parameters['postBody'] instanceof Model) {
+ // In the cases the post body is an existing object, we want
+ // to use the smart method to create a simple object for
+ // for JSONification.
+ $parameters['postBody'] = $parameters['postBody']->toSimpleObject();
+ } elseif (\is_object($parameters['postBody'])) {
+ // If the post body is another kind of object, we will try and
+ // wrangle it into a sensible format.
+ $parameters['postBody'] = $this->convertToArrayAndStripNulls($parameters['postBody']);
+ }
+ $postBody = (array) $parameters['postBody'];
+ unset($parameters['postBody']);
+ }
+ // TODO: optParams here probably should have been
+ // handled already - this may well be redundant code.
+ if (isset($parameters['optParams'])) {
+ $optParams = $parameters['optParams'];
+ unset($parameters['optParams']);
+ $parameters = \array_merge($parameters, $optParams);
+ }
+ if (!isset($method['parameters'])) {
+ $method['parameters'] = [];
+ }
+ $method['parameters'] = \array_merge($this->stackParameters, $method['parameters']);
+ foreach ($parameters as $key => $val) {
+ if ($key != 'postBody' && !isset($method['parameters'][$key])) {
+ $this->client->getLogger()->error('Service parameter unknown', ['service' => $this->serviceName, 'resource' => $this->resourceName, 'method' => $name, 'parameter' => $key]);
+ throw new GoogleException("({$name}) unknown parameter: '{$key}'");
+ }
+ }
+ foreach ($method['parameters'] as $paramName => $paramSpec) {
+ if (isset($paramSpec['required']) && $paramSpec['required'] && !isset($parameters[$paramName])) {
+ $this->client->getLogger()->error('Service parameter missing', ['service' => $this->serviceName, 'resource' => $this->resourceName, 'method' => $name, 'parameter' => $paramName]);
+ throw new GoogleException("({$name}) missing required param: '{$paramName}'");
+ }
+ if (isset($parameters[$paramName])) {
+ $value = $parameters[$paramName];
+ $parameters[$paramName] = $paramSpec;
+ $parameters[$paramName]['value'] = $value;
+ unset($parameters[$paramName]['required']);
+ } else {
+ // Ensure we don't pass nulls.
+ unset($parameters[$paramName]);
+ }
+ }
+ $this->client->getLogger()->info('Service Call', ['service' => $this->serviceName, 'resource' => $this->resourceName, 'method' => $name, 'arguments' => $parameters]);
+ // build the service uri
+ $url = $this->createRequestUri($method['path'], $parameters);
+ // NOTE: because we're creating the request by hand,
+ // and because the service has a rootUrl property
+ // the "base_uri" of the Http Client is not accounted for
+ $request = new Request($method['httpMethod'], $url, $postBody ? ['content-type' => 'application/json'] : [], $postBody ? \json_encode($postBody) : '');
+ // support uploads
+ if (isset($parameters['data'])) {
+ $mimeType = isset($parameters['mimeType']) ? $parameters['mimeType']['value'] : 'application/octet-stream';
+ $data = $parameters['data']['value'];
+ $upload = new MediaFileUpload($this->client, $request, $mimeType, $data);
+ // pull down the modified request
+ $request = $upload->getRequest();
+ }
+ // if this is a media type, we will return the raw response
+ // rather than using an expected class
+ if (isset($parameters['alt']) && $parameters['alt']['value'] == 'media') {
+ $expectedClass = null;
+ }
+ // if the client is marked for deferring, rather than
+ // execute the request, return the response
+ if ($this->client->shouldDefer()) {
+ // @TODO find a better way to do this
+ $request = $request->withHeader('X-Php-Expected-Class', $expectedClass);
+ return $request;
+ }
+ return $this->client->execute($request, $expectedClass);
+ }
+ protected function convertToArrayAndStripNulls($o)
+ {
+ $o = (array) $o;
+ foreach ($o as $k => $v) {
+ if ($v === null) {
+ unset($o[$k]);
+ } elseif (\is_object($v) || \is_array($v)) {
+ $o[$k] = $this->convertToArrayAndStripNulls($o[$k]);
+ }
+ }
+ return $o;
+ }
+ /**
+ * Parse/expand request parameters and create a fully qualified
+ * request uri.
+ * @static
+ * @param string $restPath
+ * @param array $params
+ * @return string $requestUrl
+ */
+ public function createRequestUri($restPath, $params)
+ {
+ // Override the default servicePath address if the $restPath use a /
+ if ('/' == \substr($restPath, 0, 1)) {
+ $requestUrl = \substr($restPath, 1);
+ } else {
+ $requestUrl = $this->servicePath . $restPath;
+ }
+ if ($this->rootUrlTemplate) {
+ // code for universe domain
+ $rootUrl = \str_replace('UNIVERSE_DOMAIN', $this->client->getUniverseDomain(), $this->rootUrlTemplate);
+ // code for leading slash
+ if ('/' !== \substr($rootUrl, -1) && '/' !== \substr($requestUrl, 0, 1)) {
+ $requestUrl = '/' . $requestUrl;
+ }
+ $requestUrl = $rootUrl . $requestUrl;
+ }
+ $uriTemplateVars = [];
+ $queryVars = [];
+ foreach ($params as $paramName => $paramSpec) {
+ if ($paramSpec['type'] == 'boolean') {
+ $paramSpec['value'] = $paramSpec['value'] ? 'true' : 'false';
+ }
+ if ($paramSpec['location'] == 'path') {
+ $uriTemplateVars[$paramName] = $paramSpec['value'];
+ } elseif ($paramSpec['location'] == 'query') {
+ if (\is_array($paramSpec['value'])) {
+ foreach ($paramSpec['value'] as $value) {
+ $queryVars[] = $paramName . '=' . \rawurlencode(\rawurldecode($value));
+ }
+ } else {
+ $queryVars[] = $paramName . '=' . \rawurlencode(\rawurldecode($paramSpec['value']));
+ }
+ }
+ }
+ if (\count($uriTemplateVars)) {
+ $uriTemplateParser = new UriTemplate();
+ $requestUrl = $uriTemplateParser->parse($requestUrl, $uriTemplateVars);
+ }
+ if (\count($queryVars)) {
+ $requestUrl .= '?' . \implode('&', $queryVars);
+ }
+ return $requestUrl;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/Task/Composer.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/Task/Composer.php
new file mode 100755
index 00000000..93523302
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/Task/Composer.php
@@ -0,0 +1,77 @@
+getComposer();
+ $extra = $composer->getPackage()->getExtra();
+ $servicesToKeep = isset($extra['google/apiclient-services']) ? $extra['google/apiclient-services'] : [];
+ if ($servicesToKeep) {
+ $vendorDir = $composer->getConfig()->get('vendor-dir');
+ $serviceDir = \sprintf('%s/google/apiclient-services/src/Google/Service', $vendorDir);
+ if (!\is_dir($serviceDir)) {
+ // path for google/apiclient-services >= 0.200.0
+ $serviceDir = \sprintf('%s/google/apiclient-services/src', $vendorDir);
+ }
+ self::verifyServicesToKeep($serviceDir, $servicesToKeep);
+ $finder = self::getServicesToRemove($serviceDir, $servicesToKeep);
+ $filesystem = $filesystem ?: new Filesystem();
+ if (0 !== ($count = \count($finder))) {
+ $event->getIO()->write(\sprintf('Removing %s google services', $count));
+ foreach ($finder as $file) {
+ $realpath = $file->getRealPath();
+ $filesystem->remove($realpath);
+ $filesystem->remove($realpath . '.php');
+ }
+ }
+ }
+ }
+ /**
+ * @throws InvalidArgumentException when the service doesn't exist
+ */
+ private static function verifyServicesToKeep($serviceDir, array $servicesToKeep)
+ {
+ $finder = (new Finder())->directories()->depth('== 0');
+ foreach ($servicesToKeep as $service) {
+ if (!\preg_match('/^[a-zA-Z0-9]*$/', $service)) {
+ throw new InvalidArgumentException(\sprintf('Invalid Google service name "%s"', $service));
+ }
+ try {
+ $finder->in($serviceDir . '/' . $service);
+ } catch (InvalidArgumentException $e) {
+ throw new InvalidArgumentException(\sprintf('Google service "%s" does not exist or was removed previously', $service));
+ }
+ }
+ }
+ private static function getServicesToRemove($serviceDir, array $servicesToKeep)
+ {
+ // find all files in the current directory
+ return (new Finder())->directories()->depth('== 0')->in($serviceDir)->exclude($servicesToKeep);
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/Task/Exception.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/Task/Exception.php
new file mode 100755
index 00000000..e695be7c
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/Task/Exception.php
@@ -0,0 +1,23 @@
+ self::TASK_RETRY_ALWAYS,
+ '503' => self::TASK_RETRY_ALWAYS,
+ 'rateLimitExceeded' => self::TASK_RETRY_ALWAYS,
+ 'userRateLimitExceeded' => self::TASK_RETRY_ALWAYS,
+ 6 => self::TASK_RETRY_ALWAYS,
+ // CURLE_COULDNT_RESOLVE_HOST
+ 7 => self::TASK_RETRY_ALWAYS,
+ // CURLE_COULDNT_CONNECT
+ 28 => self::TASK_RETRY_ALWAYS,
+ // CURLE_OPERATION_TIMEOUTED
+ 35 => self::TASK_RETRY_ALWAYS,
+ // CURLE_SSL_CONNECT_ERROR
+ 52 => self::TASK_RETRY_ALWAYS,
+ // CURLE_GOT_NOTHING
+ 'lighthouseError' => self::TASK_RETRY_NEVER,
+ ];
+ /**
+ * Creates a new task runner with exponential backoff support.
+ *
+ * @param array $config The task runner config
+ * @param string $name The name of the current task (used for logging)
+ * @param callable $action The task to run and possibly retry
+ * @param array $arguments The task arguments
+ * @throws \Google\Task\Exception when misconfigured
+ */
+ // @phpstan-ignore-next-line
+ public function __construct($config, $name, $action, array $arguments = [])
+ {
+ if (isset($config['initial_delay'])) {
+ if ($config['initial_delay'] < 0) {
+ throw new GoogleTaskException('Task configuration `initial_delay` must not be negative.');
+ }
+ $this->delay = $config['initial_delay'];
+ }
+ if (isset($config['max_delay'])) {
+ if ($config['max_delay'] <= 0) {
+ throw new GoogleTaskException('Task configuration `max_delay` must be greater than 0.');
+ }
+ $this->maxDelay = $config['max_delay'];
+ }
+ if (isset($config['factor'])) {
+ if ($config['factor'] <= 0) {
+ throw new GoogleTaskException('Task configuration `factor` must be greater than 0.');
+ }
+ $this->factor = $config['factor'];
+ }
+ if (isset($config['jitter'])) {
+ if ($config['jitter'] <= 0) {
+ throw new GoogleTaskException('Task configuration `jitter` must be greater than 0.');
+ }
+ $this->jitter = $config['jitter'];
+ }
+ if (isset($config['retries'])) {
+ if ($config['retries'] < 0) {
+ throw new GoogleTaskException('Task configuration `retries` must not be negative.');
+ }
+ $this->maxAttempts += $config['retries'];
+ }
+ if (!\is_callable($action)) {
+ throw new GoogleTaskException('Task argument `$action` must be a valid callable.');
+ }
+ $this->action = $action;
+ $this->arguments = $arguments;
+ }
+ /**
+ * Checks if a retry can be attempted.
+ *
+ * @return boolean
+ */
+ public function canAttempt()
+ {
+ return $this->attempts < $this->maxAttempts;
+ }
+ /**
+ * Runs the task and (if applicable) automatically retries when errors occur.
+ *
+ * @return mixed
+ * @throws \Google\Service\Exception on failure when no retries are available.
+ */
+ public function run()
+ {
+ while ($this->attempt()) {
+ try {
+ return \call_user_func_array($this->action, $this->arguments);
+ } catch (GoogleServiceException $exception) {
+ $allowedRetries = $this->allowedRetries($exception->getCode(), $exception->getErrors());
+ if (!$this->canAttempt() || !$allowedRetries) {
+ throw $exception;
+ }
+ if ($allowedRetries > 0) {
+ $this->maxAttempts = \min($this->maxAttempts, $this->attempts + $allowedRetries);
+ }
+ }
+ }
+ }
+ /**
+ * Runs a task once, if possible. This is useful for bypassing the `run()`
+ * loop.
+ *
+ * NOTE: If this is not the first attempt, this function will sleep in
+ * accordance to the backoff configurations before running the task.
+ *
+ * @return boolean
+ */
+ public function attempt()
+ {
+ if (!$this->canAttempt()) {
+ return \false;
+ }
+ if ($this->attempts > 0) {
+ $this->backOff();
+ }
+ $this->attempts++;
+ return \true;
+ }
+ /**
+ * Sleeps in accordance to the backoff configurations.
+ */
+ private function backOff()
+ {
+ $delay = $this->getDelay();
+ \usleep((int) ($delay * 1000000));
+ }
+ /**
+ * Gets the delay (in seconds) for the current backoff period.
+ *
+ * @return int
+ */
+ private function getDelay()
+ {
+ $jitter = $this->getJitter();
+ $factor = $this->attempts > 1 ? $this->factor + $jitter : 1 + \abs($jitter);
+ return $this->delay = \min($this->maxDelay, $this->delay * $factor);
+ }
+ /**
+ * Gets the current jitter (random number between -$this->jitter and
+ * $this->jitter).
+ *
+ * @return float
+ */
+ private function getJitter()
+ {
+ return $this->jitter * 2 * \mt_rand() / \mt_getrandmax() - $this->jitter;
+ }
+ /**
+ * Gets the number of times the associated task can be retried.
+ *
+ * NOTE: -1 is returned if the task can be retried indefinitely
+ *
+ * @return integer
+ */
+ public function allowedRetries($code, $errors = [])
+ {
+ if (isset($this->retryMap[$code])) {
+ return $this->retryMap[$code];
+ }
+ if (!empty($errors) && isset($errors[0]['reason'], $this->retryMap[$errors[0]['reason']])) {
+ return $this->retryMap[$errors[0]['reason']];
+ }
+ return 0;
+ }
+ public function setRetryMap($retryMap)
+ {
+ $this->retryMap = $retryMap;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/Utils/UriTemplate.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/Utils/UriTemplate.php
new file mode 100755
index 00000000..7f0b5fd7
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/Utils/UriTemplate.php
@@ -0,0 +1,264 @@
+ "reserved", "/" => "segments", "." => "dotprefix", "#" => "fragment", ";" => "semicolon", "?" => "form", "&" => "continuation"];
+ /**
+ * @var array
+ * These are the characters which should not be URL encoded in reserved
+ * strings.
+ */
+ private $reserved = ["=", ",", "!", "@", "|", ":", "/", "?", "#", "[", "]", '$', "&", "'", "(", ")", "*", "+", ";"];
+ private $reservedEncoded = ["%3D", "%2C", "%21", "%40", "%7C", "%3A", "%2F", "%3F", "%23", "%5B", "%5D", "%24", "%26", "%27", "%28", "%29", "%2A", "%2B", "%3B"];
+ public function parse($string, array $parameters)
+ {
+ return $this->resolveNextSection($string, $parameters);
+ }
+ /**
+ * This function finds the first matching {...} block and
+ * executes the replacement. It then calls itself to find
+ * subsequent blocks, if any.
+ */
+ private function resolveNextSection($string, $parameters)
+ {
+ $start = \strpos($string, "{");
+ if ($start === \false) {
+ return $string;
+ }
+ $end = \strpos($string, "}");
+ if ($end === \false) {
+ return $string;
+ }
+ $string = $this->replace($string, $start, $end, $parameters);
+ return $this->resolveNextSection($string, $parameters);
+ }
+ private function replace($string, $start, $end, $parameters)
+ {
+ // We know a data block will have {} round it, so we can strip that.
+ $data = \substr($string, $start + 1, $end - $start - 1);
+ // If the first character is one of the reserved operators, it effects
+ // the processing of the stream.
+ if (isset($this->operators[$data[0]])) {
+ $op = $this->operators[$data[0]];
+ $data = \substr($data, 1);
+ $prefix = "";
+ $prefix_on_missing = \false;
+ switch ($op) {
+ case "reserved":
+ // Reserved means certain characters should not be URL encoded
+ $data = $this->replaceVars($data, $parameters, ",", null, \true);
+ break;
+ case "fragment":
+ // Comma separated with fragment prefix. Bare values only.
+ $prefix = "#";
+ $prefix_on_missing = \true;
+ $data = $this->replaceVars($data, $parameters, ",", null, \true);
+ break;
+ case "segments":
+ // Slash separated data. Bare values only.
+ $prefix = "/";
+ $data = $this->replaceVars($data, $parameters, "/");
+ break;
+ case "dotprefix":
+ // Dot separated data. Bare values only.
+ $prefix = ".";
+ $prefix_on_missing = \true;
+ $data = $this->replaceVars($data, $parameters, ".");
+ break;
+ case "semicolon":
+ // Semicolon prefixed and separated. Uses the key name
+ $prefix = ";";
+ $data = $this->replaceVars($data, $parameters, ";", "=", \false, \true, \false);
+ break;
+ case "form":
+ // Standard URL format. Uses the key name
+ $prefix = "?";
+ $data = $this->replaceVars($data, $parameters, "&", "=");
+ break;
+ case "continuation":
+ // Standard URL, but with leading ampersand. Uses key name.
+ $prefix = "&";
+ $data = $this->replaceVars($data, $parameters, "&", "=");
+ break;
+ }
+ // Add the initial prefix character if data is valid.
+ if ($data || $data !== \false && $prefix_on_missing) {
+ $data = $prefix . $data;
+ }
+ } else {
+ // If no operator we replace with the defaults.
+ $data = $this->replaceVars($data, $parameters);
+ }
+ // This is chops out the {...} and replaces with the new section.
+ return \substr($string, 0, $start) . $data . \substr($string, $end + 1);
+ }
+ private function replaceVars($section, $parameters, $sep = ",", $combine = null, $reserved = \false, $tag_empty = \false, $combine_on_empty = \true)
+ {
+ if (\strpos($section, ",") === \false) {
+ // If we only have a single value, we can immediately process.
+ return $this->combine($section, $parameters, $sep, $combine, $reserved, $tag_empty, $combine_on_empty);
+ } else {
+ // If we have multiple values, we need to split and loop over them.
+ // Each is treated individually, then glued together with the
+ // separator character.
+ $vars = \explode(",", $section);
+ return $this->combineList(
+ $vars,
+ $sep,
+ $parameters,
+ $combine,
+ $reserved,
+ \false,
+ // Never emit empty strings in multi-param replacements
+ $combine_on_empty
+ );
+ }
+ }
+ public function combine($key, $parameters, $sep, $combine, $reserved, $tag_empty, $combine_on_empty)
+ {
+ $length = \false;
+ $explode = \false;
+ $skip_final_combine = \false;
+ $value = \false;
+ // Check for length restriction.
+ if (\strpos($key, ":") !== \false) {
+ list($key, $length) = \explode(":", $key);
+ }
+ // Check for explode parameter.
+ if ($key[\strlen($key) - 1] == "*") {
+ $explode = \true;
+ $key = \substr($key, 0, -1);
+ $skip_final_combine = \true;
+ }
+ // Define the list separator.
+ $list_sep = $explode ? $sep : ",";
+ if (isset($parameters[$key])) {
+ $data_type = $this->getDataType($parameters[$key]);
+ switch ($data_type) {
+ case self::TYPE_SCALAR:
+ $value = $this->getValue($parameters[$key], $length);
+ break;
+ case self::TYPE_LIST:
+ $values = [];
+ foreach ($parameters[$key] as $pkey => $pvalue) {
+ $pvalue = $this->getValue($pvalue, $length);
+ if ($combine && $explode) {
+ $values[$pkey] = $key . $combine . $pvalue;
+ } else {
+ $values[$pkey] = $pvalue;
+ }
+ }
+ $value = \implode($list_sep, $values);
+ if ($value == '') {
+ return '';
+ }
+ break;
+ case self::TYPE_MAP:
+ $values = [];
+ foreach ($parameters[$key] as $pkey => $pvalue) {
+ $pvalue = $this->getValue($pvalue, $length);
+ if ($explode) {
+ $pkey = $this->getValue($pkey, $length);
+ $values[] = $pkey . "=" . $pvalue;
+ // Explode triggers = combine.
+ } else {
+ $values[] = $pkey;
+ $values[] = $pvalue;
+ }
+ }
+ $value = \implode($list_sep, $values);
+ if ($value == '') {
+ return \false;
+ }
+ break;
+ }
+ } elseif ($tag_empty) {
+ // If we are just indicating empty values with their key name, return that.
+ return $key;
+ } else {
+ // Otherwise we can skip this variable due to not being defined.
+ return \false;
+ }
+ if ($reserved) {
+ $value = \str_replace($this->reservedEncoded, $this->reserved, $value);
+ }
+ // If we do not need to include the key name, we just return the raw
+ // value.
+ if (!$combine || $skip_final_combine) {
+ return $value;
+ }
+ // Else we combine the key name: foo=bar, if value is not the empty string.
+ return $key . ($value != '' || $combine_on_empty ? $combine . $value : '');
+ }
+ /**
+ * Return the type of a passed in value
+ */
+ private function getDataType($data)
+ {
+ if (\is_array($data)) {
+ \reset($data);
+ if (\key($data) !== 0) {
+ return self::TYPE_MAP;
+ }
+ return self::TYPE_LIST;
+ }
+ return self::TYPE_SCALAR;
+ }
+ /**
+ * Utility function that merges multiple combine calls
+ * for multi-key templates.
+ */
+ private function combineList($vars, $sep, $parameters, $combine, $reserved, $tag_empty, $combine_on_empty)
+ {
+ $ret = [];
+ foreach ($vars as $var) {
+ $response = $this->combine($var, $parameters, $sep, $combine, $reserved, $tag_empty, $combine_on_empty);
+ if ($response === \false) {
+ continue;
+ }
+ $ret[] = $response;
+ }
+ return \implode($sep, $ret);
+ }
+ /**
+ * Utility function to encode and trim values
+ */
+ private function getValue($value, $length)
+ {
+ if ($length) {
+ $value = \substr($value, 0, $length);
+ }
+ $value = \rawurlencode($value);
+ return $value;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/aliases.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/aliases.php
new file mode 100755
index 00000000..63e33b86
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/aliases.php
@@ -0,0 +1,80 @@
+ 'Google_Client', 'WPMailSMTP\\Vendor\\Google\\Service' => 'Google_Service', 'WPMailSMTP\\Vendor\\Google\\AccessToken\\Revoke' => 'Google_AccessToken_Revoke', 'WPMailSMTP\\Vendor\\Google\\AccessToken\\Verify' => 'Google_AccessToken_Verify', 'WPMailSMTP\\Vendor\\Google\\Model' => 'Google_Model', 'WPMailSMTP\\Vendor\\Google\\Utils\\UriTemplate' => 'Google_Utils_UriTemplate', 'WPMailSMTP\\Vendor\\Google\\AuthHandler\\Guzzle6AuthHandler' => 'Google_AuthHandler_Guzzle6AuthHandler', 'WPMailSMTP\\Vendor\\Google\\AuthHandler\\Guzzle7AuthHandler' => 'Google_AuthHandler_Guzzle7AuthHandler', 'WPMailSMTP\\Vendor\\Google\\AuthHandler\\AuthHandlerFactory' => 'Google_AuthHandler_AuthHandlerFactory', 'WPMailSMTP\\Vendor\\Google\\Http\\Batch' => 'Google_Http_Batch', 'WPMailSMTP\\Vendor\\Google\\Http\\MediaFileUpload' => 'Google_Http_MediaFileUpload', 'WPMailSMTP\\Vendor\\Google\\Http\\REST' => 'Google_Http_REST', 'WPMailSMTP\\Vendor\\Google\\Task\\Retryable' => 'Google_Task_Retryable', 'WPMailSMTP\\Vendor\\Google\\Task\\Exception' => 'Google_Task_Exception', 'WPMailSMTP\\Vendor\\Google\\Task\\Runner' => 'Google_Task_Runner', 'WPMailSMTP\\Vendor\\Google\\Collection' => 'Google_Collection', 'WPMailSMTP\\Vendor\\Google\\Service\\Exception' => 'Google_Service_Exception', 'WPMailSMTP\\Vendor\\Google\\Service\\Resource' => 'Google_Service_Resource', 'WPMailSMTP\\Vendor\\Google\\Exception' => 'Google_Exception'];
+foreach ($classMap as $class => $alias) {
+ \class_alias($class, 'WPMailSMTP\\Vendor\\' . $alias);
+}
+/**
+ * This class needs to be defined explicitly as scripts must be recognized by
+ * the autoloader.
+ */
+class Google_Task_Composer extends \WPMailSMTP\Vendor\Google\Task\Composer
+{
+}
+/** @phpstan-ignore-next-line */
+if (\false) {
+ class Google_AccessToken_Revoke extends \WPMailSMTP\Vendor\Google\AccessToken\Revoke
+ {
+ }
+ class Google_AccessToken_Verify extends \WPMailSMTP\Vendor\Google\AccessToken\Verify
+ {
+ }
+ class Google_AuthHandler_AuthHandlerFactory extends \WPMailSMTP\Vendor\Google\AuthHandler\AuthHandlerFactory
+ {
+ }
+ class Google_AuthHandler_Guzzle6AuthHandler extends \WPMailSMTP\Vendor\Google\AuthHandler\Guzzle6AuthHandler
+ {
+ }
+ class Google_AuthHandler_Guzzle7AuthHandler extends \WPMailSMTP\Vendor\Google\AuthHandler\Guzzle7AuthHandler
+ {
+ }
+ class Google_Client extends \WPMailSMTP\Vendor\Google\Client
+ {
+ }
+ class Google_Collection extends \WPMailSMTP\Vendor\Google\Collection
+ {
+ }
+ class Google_Exception extends \WPMailSMTP\Vendor\Google\Exception
+ {
+ }
+ class Google_Http_Batch extends \WPMailSMTP\Vendor\Google\Http\Batch
+ {
+ }
+ class Google_Http_MediaFileUpload extends \WPMailSMTP\Vendor\Google\Http\MediaFileUpload
+ {
+ }
+ class Google_Http_REST extends \WPMailSMTP\Vendor\Google\Http\REST
+ {
+ }
+ class Google_Model extends \WPMailSMTP\Vendor\Google\Model
+ {
+ }
+ class Google_Service extends \WPMailSMTP\Vendor\Google\Service
+ {
+ }
+ class Google_Service_Exception extends \WPMailSMTP\Vendor\Google\Service\Exception
+ {
+ }
+ class Google_Service_Resource extends \WPMailSMTP\Vendor\Google\Service\Resource
+ {
+ }
+ class Google_Task_Exception extends \WPMailSMTP\Vendor\Google\Task\Exception
+ {
+ }
+ interface Google_Task_Retryable extends \WPMailSMTP\Vendor\Google\Task\Retryable
+ {
+ }
+ class Google_Task_Runner extends \WPMailSMTP\Vendor\Google\Task\Runner
+ {
+ }
+ class Google_Utils_UriTemplate extends \WPMailSMTP\Vendor\Google\Utils\UriTemplate
+ {
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/LICENSE b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/LICENSE
new file mode 100755
index 00000000..a148ba56
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/LICENSE
@@ -0,0 +1,203 @@
+Apache License
+Version 2.0, January 2004
+http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+"License" shall mean the terms and conditions for use, reproduction,
+and distribution as defined by Sections 1 through 9 of this document.
+
+"Licensor" shall mean the copyright owner or entity authorized by
+the copyright owner that is granting the License.
+
+"Legal Entity" shall mean the union of the acting entity and all
+other entities that control, are controlled by, or are under common
+control with that entity. For the purposes of this definition,
+"control" means (i) the power, direct or indirect, to cause the
+direction or management of such entity, whether by contract or
+otherwise, or (ii) ownership of fifty percent (50%) or more of the
+outstanding shares, or (iii) beneficial ownership of such entity.
+
+"You" (or "Your") shall mean an individual or Legal Entity
+exercising permissions granted by this License.
+
+"Source" form shall mean the preferred form for making modifications,
+including but not limited to software source code, documentation
+source, and configuration files.
+
+"Object" form shall mean any form resulting from mechanical
+transformation or translation of a Source form, including but
+not limited to compiled object code, generated documentation,
+and conversions to other media types.
+
+"Work" shall mean the work of authorship, whether in Source or
+Object form, made available under the License, as indicated by a
+copyright notice that is included in or attached to the work
+(an example is provided in the Appendix below).
+
+"Derivative Works" shall mean any work, whether in Source or Object
+form, that is based on (or derived from) the Work and for which the
+editorial revisions, annotations, elaborations, or other modifications
+represent, as a whole, an original work of authorship. For the purposes
+of this License, Derivative Works shall not include works that remain
+separable from, or merely link (or bind by name) to the interfaces of,
+the Work and Derivative Works thereof.
+
+"Contribution" shall mean any work of authorship, including
+the original version of the Work and any modifications or additions
+to that Work or Derivative Works thereof, that is intentionally
+submitted to Licensor for inclusion in the Work by the copyright owner
+or by an individual or Legal Entity authorized to submit on behalf of
+the copyright owner. For the purposes of this definition, "submitted"
+means any form of electronic, verbal, or written communication sent
+to the Licensor or its representatives, including but not limited to
+communication on electronic mailing lists, source code control systems,
+and issue tracking systems that are managed by, or on behalf of, the
+Licensor for the purpose of discussing and improving the Work, but
+excluding communication that is conspicuously marked or otherwise
+designated in writing by the copyright owner as "Not a Contribution."
+
+"Contributor" shall mean Licensor and any individual or Legal Entity
+on behalf of whom a Contribution has been received by Licensor and
+subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+this License, each Contributor hereby grants to You a perpetual,
+worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+copyright license to reproduce, prepare Derivative Works of,
+publicly display, publicly perform, sublicense, and distribute the
+Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+this License, each Contributor hereby grants to You a perpetual,
+worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+(except as stated in this section) patent license to make, have made,
+use, offer to sell, sell, import, and otherwise transfer the Work,
+where such license applies only to those patent claims licensable
+by such Contributor that are necessarily infringed by their
+Contribution(s) alone or by combination of their Contribution(s)
+with the Work to which such Contribution(s) was submitted. If You
+institute patent litigation against any entity (including a
+cross-claim or counterclaim in a lawsuit) alleging that the Work
+or a Contribution incorporated within the Work constitutes direct
+or contributory patent infringement, then any patent licenses
+granted to You under this License for that Work shall terminate
+as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+Work or Derivative Works thereof in any medium, with or without
+modifications, and in Source or Object form, provided that You
+meet the following conditions:
+
+(a) You must give any other recipients of the Work or
+Derivative Works a copy of this License; and
+
+(b) You must cause any modified files to carry prominent notices
+stating that You changed the files; and
+
+(c) You must retain, in the Source form of any Derivative Works
+that You distribute, all copyright, patent, trademark, and
+attribution notices from the Source form of the Work,
+excluding those notices that do not pertain to any part of
+the Derivative Works; and
+
+(d) If the Work includes a "NOTICE" text file as part of its
+distribution, then any Derivative Works that You distribute must
+include a readable copy of the attribution notices contained
+within such NOTICE file, excluding those notices that do not
+pertain to any part of the Derivative Works, in at least one
+of the following places: within a NOTICE text file distributed
+as part of the Derivative Works; within the Source form or
+documentation, if provided along with the Derivative Works; or,
+within a display generated by the Derivative Works, if and
+wherever such third-party notices normally appear. The contents
+of the NOTICE file are for informational purposes only and
+do not modify the License. You may add Your own attribution
+notices within Derivative Works that You distribute, alongside
+or as an addendum to the NOTICE text from the Work, provided
+that such additional attribution notices cannot be construed
+as modifying the License.
+
+You may add Your own copyright statement to Your modifications and
+may provide additional or different license terms and conditions
+for use, reproduction, or distribution of Your modifications, or
+for any such Derivative Works as a whole, provided Your use,
+reproduction, and distribution of the Work otherwise complies with
+the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+any Contribution intentionally submitted for inclusion in the Work
+by You to the Licensor shall be under the terms and conditions of
+this License, without any additional terms or conditions.
+Notwithstanding the above, nothing herein shall supersede or modify
+the terms of any separate license agreement you may have executed
+with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+names, trademarks, service marks, or product names of the Licensor,
+except as required for reasonable and customary use in describing the
+origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+agreed to in writing, Licensor provides the Work (and each
+Contributor provides its Contributions) on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+implied, including, without limitation, any warranties or conditions
+of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+PARTICULAR PURPOSE. You are solely responsible for determining the
+appropriateness of using or redistributing the Work and assume any
+risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+whether in tort (including negligence), contract, or otherwise,
+unless required by applicable law (such as deliberate and grossly
+negligent acts) or agreed to in writing, shall any Contributor be
+liable to You for damages, including any direct, indirect, special,
+incidental, or consequential damages of any character arising as a
+result of this License or out of the use or inability to use the
+Work (including but not limited to damages for loss of goodwill,
+work stoppage, computer failure or malfunction, or any and all
+other commercial damages or losses), even if such Contributor
+has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+the Work or Derivative Works thereof, You may choose to offer,
+and charge a fee for, acceptance of support, warranty, indemnity,
+or other liability obligations and/or rights consistent with this
+License. However, in accepting such obligations, You may act only
+on Your own behalf and on Your sole responsibility, not on behalf
+of any other Contributor, and only if You agree to indemnify,
+defend, and hold each Contributor harmless for any liability
+incurred by, or claims asserted against, such Contributor by reason
+of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+To apply the Apache License to your work, attach the following
+boilerplate notice, with the fields enclosed by brackets "[]"
+replaced with your own identifying information. (Don't include
+the brackets!) The text should be enclosed in the appropriate
+comment syntax for the file format. We also recommend that a
+file or class name and description of purpose be included on the
+same "printed page" as the copyright notice for easier
+identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/autoload.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/autoload.php
new file mode 100755
index 00000000..0eef41b0
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/autoload.php
@@ -0,0 +1,35 @@
+ 3) {
+ // Maximum class file path depth in this project is 3.
+ $classPath = \array_slice($classPath, 0, 3);
+ }
+ $filePath = \dirname(__FILE__) . '/src/' . \implode('/', $classPath) . '.php';
+ if (\file_exists($filePath)) {
+ require_once $filePath;
+ }
+}
+\spl_autoload_register('oauth2client_php_autoload');
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/AccessToken.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/AccessToken.php
new file mode 100755
index 00000000..9d3b09ad
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/AccessToken.php
@@ -0,0 +1,390 @@
+httpHandler = $httpHandler ?: HttpHandlerFactory::build(HttpClientCache::getHttpClient());
+ $this->cache = $cache ?: new MemoryCacheItemPool();
+ }
+ /**
+ * Verifies an id token and returns the authenticated apiLoginTicket.
+ * Throws an exception if the id token is not valid.
+ * The audience parameter can be used to control which id tokens are
+ * accepted. By default, the id token must have been issued to this OAuth2 client.
+ *
+ * @param string $token The JSON Web Token to be verified.
+ * @param array $options [optional] {
+ * Configuration options.
+ * @type string $audience The indended recipient of the token.
+ * @type string $issuer The intended issuer of the token.
+ * @type string $cacheKey The cache key of the cached certs. Defaults to
+ * the sha1 of $certsLocation if provided, otherwise is set to
+ * "federated_signon_certs_v3".
+ * @type string $certsLocation The location (remote or local) from which
+ * to retrieve certificates, if not cached. This value should only be
+ * provided in limited circumstances in which you are sure of the
+ * behavior.
+ * @type bool $throwException Whether the function should throw an
+ * exception if the verification fails. This is useful for
+ * determining the reason verification failed.
+ * }
+ * @return array|false the token payload, if successful, or false if not.
+ * @throws InvalidArgumentException If certs could not be retrieved from a local file.
+ * @throws InvalidArgumentException If received certs are in an invalid format.
+ * @throws InvalidArgumentException If the cert alg is not supported.
+ * @throws RuntimeException If certs could not be retrieved from a remote location.
+ * @throws UnexpectedValueException If the token issuer does not match.
+ * @throws UnexpectedValueException If the token audience does not match.
+ */
+ public function verify($token, array $options = [])
+ {
+ $audience = $options['audience'] ?? null;
+ $issuer = $options['issuer'] ?? null;
+ $certsLocation = $options['certsLocation'] ?? self::FEDERATED_SIGNON_CERT_URL;
+ $cacheKey = $options['cacheKey'] ?? $this->getCacheKeyFromCertLocation($certsLocation);
+ $throwException = $options['throwException'] ?? \false;
+ // for backwards compatibility
+ // Check signature against each available cert.
+ $certs = $this->getCerts($certsLocation, $cacheKey, $options);
+ $alg = $this->determineAlg($certs);
+ if (!\in_array($alg, ['RS256', 'ES256'])) {
+ throw new InvalidArgumentException('unrecognized "alg" in certs, expected ES256 or RS256');
+ }
+ try {
+ if ($alg == 'RS256') {
+ return $this->verifyRs256($token, $certs, $audience, $issuer);
+ }
+ return $this->verifyEs256($token, $certs, $audience, $issuer);
+ } catch (ExpiredException $e) {
+ // firebase/php-jwt 5+
+ } catch (SignatureInvalidException $e) {
+ // firebase/php-jwt 5+
+ } catch (InvalidTokenException $e) {
+ // simplejwt
+ } catch (InvalidArgumentException $e) {
+ } catch (UnexpectedValueException $e) {
+ }
+ if ($throwException) {
+ throw $e;
+ }
+ return \false;
+ }
+ /**
+ * Identifies the expected algorithm to verify by looking at the "alg" key
+ * of the provided certs.
+ *
+ * @param array $certs Certificate array according to the JWK spec (see
+ * https://tools.ietf.org/html/rfc7517).
+ * @return string The expected algorithm, such as "ES256" or "RS256".
+ */
+ private function determineAlg(array $certs)
+ {
+ $alg = null;
+ foreach ($certs as $cert) {
+ if (empty($cert['alg'])) {
+ throw new InvalidArgumentException('certs expects "alg" to be set');
+ }
+ $alg = $alg ?: $cert['alg'];
+ if ($alg != $cert['alg']) {
+ throw new InvalidArgumentException('More than one alg detected in certs');
+ }
+ }
+ return $alg;
+ }
+ /**
+ * Verifies an ES256-signed JWT.
+ *
+ * @param string $token The JSON Web Token to be verified.
+ * @param array $certs Certificate array according to the JWK spec (see
+ * https://tools.ietf.org/html/rfc7517).
+ * @param string|null $audience If set, returns false if the provided
+ * audience does not match the "aud" claim on the JWT.
+ * @param string|null $issuer If set, returns false if the provided
+ * issuer does not match the "iss" claim on the JWT.
+ * @return array the token payload, if successful, or false if not.
+ */
+ private function verifyEs256($token, array $certs, $audience = null, $issuer = null)
+ {
+ $this->checkSimpleJwt();
+ $jwkset = new KeySet();
+ foreach ($certs as $cert) {
+ $jwkset->add(KeyFactory::create($cert, 'php'));
+ }
+ // Validate the signature using the key set and ES256 algorithm.
+ $jwt = $this->callSimpleJwtDecode([$token, $jwkset, 'ES256']);
+ $payload = $jwt->getClaims();
+ if ($audience) {
+ if (!isset($payload['aud']) || $payload['aud'] != $audience) {
+ throw new UnexpectedValueException('Audience does not match');
+ }
+ }
+ // @see https://cloud.google.com/iap/docs/signed-headers-howto#verifying_the_jwt_payload
+ $issuer = $issuer ?: self::IAP_ISSUER;
+ if (!isset($payload['iss']) || $payload['iss'] !== $issuer) {
+ throw new UnexpectedValueException('Issuer does not match');
+ }
+ return $payload;
+ }
+ /**
+ * Verifies an RS256-signed JWT.
+ *
+ * @param string $token The JSON Web Token to be verified.
+ * @param array $certs Certificate array according to the JWK spec (see
+ * https://tools.ietf.org/html/rfc7517).
+ * @param string|null $audience If set, returns false if the provided
+ * audience does not match the "aud" claim on the JWT.
+ * @param string|null $issuer If set, returns false if the provided
+ * issuer does not match the "iss" claim on the JWT.
+ * @return array the token payload, if successful, or false if not.
+ */
+ private function verifyRs256($token, array $certs, $audience = null, $issuer = null)
+ {
+ $this->checkAndInitializePhpsec();
+ $keys = [];
+ foreach ($certs as $cert) {
+ if (empty($cert['kid'])) {
+ throw new InvalidArgumentException('certs expects "kid" to be set');
+ }
+ if (empty($cert['n']) || empty($cert['e'])) {
+ throw new InvalidArgumentException('RSA certs expects "n" and "e" to be set');
+ }
+ $publicKey = $this->loadPhpsecPublicKey($cert['n'], $cert['e']);
+ // create an array of key IDs to certs for the JWT library
+ $keys[$cert['kid']] = new Key($publicKey, 'RS256');
+ }
+ $payload = $this->callJwtStatic('decode', [$token, $keys]);
+ if ($audience) {
+ if (!\property_exists($payload, 'aud') || $payload->aud != $audience) {
+ throw new UnexpectedValueException('Audience does not match');
+ }
+ }
+ // support HTTP and HTTPS issuers
+ // @see https://developers.google.com/identity/sign-in/web/backend-auth
+ $issuers = $issuer ? [$issuer] : [self::OAUTH2_ISSUER, self::OAUTH2_ISSUER_HTTPS];
+ if (!isset($payload->iss) || !\in_array($payload->iss, $issuers)) {
+ throw new UnexpectedValueException('Issuer does not match');
+ }
+ return (array) $payload;
+ }
+ /**
+ * Revoke an OAuth2 access token or refresh token. This method will revoke the current access
+ * token, if a token isn't provided.
+ *
+ * @param string|array $token The token (access token or a refresh token) that should be revoked.
+ * @param array $options [optional] Configuration options.
+ * @return bool Returns True if the revocation was successful, otherwise False.
+ */
+ public function revoke($token, array $options = [])
+ {
+ if (\is_array($token)) {
+ if (isset($token['refresh_token'])) {
+ $token = $token['refresh_token'];
+ } else {
+ $token = $token['access_token'];
+ }
+ }
+ $body = Utils::streamFor(\http_build_query(['token' => $token]));
+ $request = new Request('POST', self::OAUTH2_REVOKE_URI, ['Cache-Control' => 'no-store', 'Content-Type' => 'application/x-www-form-urlencoded'], $body);
+ $httpHandler = $this->httpHandler;
+ $response = $httpHandler($request, $options);
+ return $response->getStatusCode() == 200;
+ }
+ /**
+ * Gets federated sign-on certificates to use for verifying identity tokens.
+ * Returns certs as array structure, where keys are key ids, and values
+ * are PEM encoded certificates.
+ *
+ * @param string $location The location from which to retrieve certs.
+ * @param string $cacheKey The key under which to cache the retrieved certs.
+ * @param array $options [optional] Configuration options.
+ * @return array
+ * @throws InvalidArgumentException If received certs are in an invalid format.
+ */
+ private function getCerts($location, $cacheKey, array $options = [])
+ {
+ $cacheItem = $this->cache->getItem($cacheKey);
+ $certs = $cacheItem ? $cacheItem->get() : null;
+ $expireTime = null;
+ if (!$certs) {
+ list($certs, $expireTime) = $this->retrieveCertsFromLocation($location, $options);
+ }
+ if (!isset($certs['keys'])) {
+ if ($location !== self::IAP_CERT_URL) {
+ throw new InvalidArgumentException('federated sign-on certs expects "keys" to be set');
+ }
+ throw new InvalidArgumentException('certs expects "keys" to be set');
+ }
+ // Push caching off until after verifying certs are in a valid format.
+ // Don't want to cache bad data.
+ if ($expireTime) {
+ $cacheItem->expiresAt(new DateTime($expireTime));
+ $cacheItem->set($certs);
+ $this->cache->save($cacheItem);
+ }
+ return $certs['keys'];
+ }
+ /**
+ * Retrieve and cache a certificates file.
+ *
+ * @param string $url location
+ * @param array $options [optional] Configuration options.
+ * @return array{array, string}
+ * @throws InvalidArgumentException If certs could not be retrieved from a local file.
+ * @throws RuntimeException If certs could not be retrieved from a remote location.
+ */
+ private function retrieveCertsFromLocation($url, array $options = [])
+ {
+ // If we're retrieving a local file, just grab it.
+ $expireTime = '+1 hour';
+ if (\strpos($url, 'http') !== 0) {
+ if (!\file_exists($url)) {
+ throw new InvalidArgumentException(\sprintf('Failed to retrieve verification certificates from path: %s.', $url));
+ }
+ return [\json_decode((string) \file_get_contents($url), \true), $expireTime];
+ }
+ $httpHandler = $this->httpHandler;
+ $response = $httpHandler(new Request('GET', $url), $options);
+ if ($response->getStatusCode() == 200) {
+ if ($cacheControl = $response->getHeaderLine('Cache-Control')) {
+ \array_map(function ($value) use(&$expireTime) {
+ list($key, $value) = \explode('=', $value) + [null, null];
+ if (\trim($key) == 'max-age') {
+ $expireTime = '+' . $value . ' seconds';
+ }
+ }, \explode(',', $cacheControl));
+ }
+ return [\json_decode((string) $response->getBody(), \true), $expireTime];
+ }
+ throw new RuntimeException(\sprintf('Failed to retrieve verification certificates: "%s".', $response->getBody()->getContents()), $response->getStatusCode());
+ }
+ /**
+ * @return void
+ */
+ private function checkAndInitializePhpsec()
+ {
+ if (!\class_exists(RSA::class)) {
+ throw new RuntimeException('Please require phpseclib/phpseclib v3 to use this utility.');
+ }
+ }
+ /**
+ * @return string
+ * @throws TypeError If the key cannot be initialized to a string.
+ */
+ private function loadPhpsecPublicKey(string $modulus, string $exponent) : string
+ {
+ $key = PublicKeyLoader::load(['n' => new BigInteger($this->callJwtStatic('urlsafeB64Decode', [$modulus]), 256), 'e' => new BigInteger($this->callJwtStatic('urlsafeB64Decode', [$exponent]), 256)]);
+ $formattedPublicKey = $key->toString('PKCS8');
+ if (!\is_string($formattedPublicKey)) {
+ throw new TypeError('Failed to initialize the key');
+ }
+ return $formattedPublicKey;
+ }
+ /**
+ * @return void
+ */
+ private function checkSimpleJwt()
+ {
+ // @codeCoverageIgnoreStart
+ if (!\class_exists(SimpleJwt::class)) {
+ throw new RuntimeException('Please require kelvinmo/simplejwt ^0.2 to use this utility.');
+ }
+ // @codeCoverageIgnoreEnd
+ }
+ /**
+ * Provide a hook to mock calls to the JWT static methods.
+ *
+ * @param string $method
+ * @param array $args
+ * @return mixed
+ */
+ protected function callJwtStatic($method, array $args = [])
+ {
+ return \call_user_func_array([JWT::class, $method], $args);
+ // @phpstan-ignore-line
+ }
+ /**
+ * Provide a hook to mock calls to the JWT static methods.
+ *
+ * @param array $args
+ * @return mixed
+ */
+ protected function callSimpleJwtDecode(array $args = [])
+ {
+ return \call_user_func_array([SimpleJwt::class, 'decode'], $args);
+ }
+ /**
+ * Generate a cache key based on the cert location using sha1 with the
+ * exception of using "federated_signon_certs_v3" to preserve BC.
+ *
+ * @param string $certsLocation
+ * @return string
+ */
+ private function getCacheKeyFromCertLocation($certsLocation)
+ {
+ $key = $certsLocation === self::FEDERATED_SIGNON_CERT_URL ? 'federated_signon_certs_v3' : \sha1($certsLocation);
+ return 'google_auth_certs_cache|' . $key;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/ApplicationDefaultCredentials.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/ApplicationDefaultCredentials.php
new file mode 100755
index 00000000..5f537a89
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/ApplicationDefaultCredentials.php
@@ -0,0 +1,301 @@
+push($middleware);
+ *
+ * $client = new Client([
+ * 'handler' => $stack,
+ * 'base_uri' => 'https://www.googleapis.com/taskqueue/v1beta2/projects/',
+ * 'auth' => 'google_auth' // authorize all requests
+ * ]);
+ *
+ * $res = $client->get('myproject/taskqueues/myqueue');
+ * ```
+ */
+class ApplicationDefaultCredentials
+{
+ /**
+ * @deprecated
+ *
+ * Obtains an AuthTokenSubscriber that uses the default FetchAuthTokenInterface
+ * implementation to use in this environment.
+ *
+ * If supplied, $scope is used to in creating the credentials instance if
+ * this does not fallback to the compute engine defaults.
+ *
+ * @param string|string[] $scope the scope of the access request, expressed
+ * either as an Array or as a space-delimited String.
+ * @param callable $httpHandler callback which delivers psr7 request
+ * @param array $cacheConfig configuration for the cache when it's present
+ * @param CacheItemPoolInterface $cache A cache implementation, may be
+ * provided if you have one already available for use.
+ * @return AuthTokenSubscriber
+ * @throws DomainException if no implementation can be obtained.
+ */
+ public static function getSubscriber(
+ // @phpstan-ignore-line
+ $scope = null,
+ ?callable $httpHandler = null,
+ ?array $cacheConfig = null,
+ ?CacheItemPoolInterface $cache = null
+ )
+ {
+ $creds = self::getCredentials($scope, $httpHandler, $cacheConfig, $cache);
+ /** @phpstan-ignore-next-line */
+ return new AuthTokenSubscriber($creds, $httpHandler);
+ }
+ /**
+ * Obtains an AuthTokenMiddleware that uses the default FetchAuthTokenInterface
+ * implementation to use in this environment.
+ *
+ * If supplied, $scope is used to in creating the credentials instance if
+ * this does not fallback to the compute engine defaults.
+ *
+ * @param string|string[] $scope the scope of the access request, expressed
+ * either as an Array or as a space-delimited String.
+ * @param callable $httpHandler callback which delivers psr7 request
+ * @param array $cacheConfig configuration for the cache when it's present
+ * @param CacheItemPoolInterface $cache A cache implementation, may be
+ * provided if you have one already available for use.
+ * @param string $quotaProject specifies a project to bill for access
+ * charges associated with the request.
+ * @return AuthTokenMiddleware
+ * @throws DomainException if no implementation can be obtained.
+ */
+ public static function getMiddleware($scope = null, ?callable $httpHandler = null, ?array $cacheConfig = null, ?CacheItemPoolInterface $cache = null, $quotaProject = null)
+ {
+ $creds = self::getCredentials($scope, $httpHandler, $cacheConfig, $cache, $quotaProject);
+ return new AuthTokenMiddleware($creds, $httpHandler);
+ }
+ /**
+ * Obtains the default FetchAuthTokenInterface implementation to use
+ * in this environment.
+ *
+ * @param string|string[] $scope the scope of the access request, expressed
+ * either as an Array or as a space-delimited String.
+ * @param callable $httpHandler callback which delivers psr7 request
+ * @param array $cacheConfig configuration for the cache when it's present
+ * @param CacheItemPoolInterface $cache A cache implementation, may be
+ * provided if you have one already available for use.
+ * @param string $quotaProject specifies a project to bill for access
+ * charges associated with the request.
+ * @param string|string[] $defaultScope The default scope to use if no
+ * user-defined scopes exist, expressed either as an Array or as a
+ * space-delimited string.
+ * @param string $universeDomain Specifies a universe domain to use for the
+ * calling client library
+ *
+ * @return FetchAuthTokenInterface
+ * @throws DomainException if no implementation can be obtained.
+ */
+ public static function getCredentials($scope = null, ?callable $httpHandler = null, ?array $cacheConfig = null, ?CacheItemPoolInterface $cache = null, $quotaProject = null, $defaultScope = null, ?string $universeDomain = null)
+ {
+ $creds = null;
+ $jsonKey = CredentialsLoader::fromEnv() ?: CredentialsLoader::fromWellKnownFile();
+ $anyScope = $scope ?: $defaultScope;
+ if (!$httpHandler) {
+ if (!($client = HttpClientCache::getHttpClient())) {
+ $client = new Client();
+ HttpClientCache::setHttpClient($client);
+ }
+ $httpHandler = HttpHandlerFactory::build($client);
+ }
+ if (\is_null($quotaProject)) {
+ // if a quota project isn't specified, try to get one from the env var
+ $quotaProject = CredentialsLoader::quotaProjectFromEnv();
+ }
+ if (!\is_null($jsonKey)) {
+ if ($quotaProject) {
+ $jsonKey['quota_project_id'] = $quotaProject;
+ }
+ if ($universeDomain) {
+ $jsonKey['universe_domain'] = $universeDomain;
+ }
+ $creds = CredentialsLoader::makeCredentials($scope, $jsonKey, $defaultScope);
+ } elseif (AppIdentityCredentials::onAppEngine() && !GCECredentials::onAppEngineFlexible()) {
+ $creds = new AppIdentityCredentials($anyScope);
+ } elseif (self::onGce($httpHandler, $cacheConfig, $cache)) {
+ $creds = new GCECredentials(null, $anyScope, null, $quotaProject, null, $universeDomain);
+ $creds->setIsOnGce(\true);
+ // save the credentials a trip to the metadata server
+ }
+ if (\is_null($creds)) {
+ throw new DomainException(self::notFound());
+ }
+ if (!\is_null($cache)) {
+ $creds = new FetchAuthTokenCache($creds, $cacheConfig, $cache);
+ }
+ return $creds;
+ }
+ /**
+ * Obtains an AuthTokenMiddleware which will fetch an ID token to use in the
+ * Authorization header. The middleware is configured with the default
+ * FetchAuthTokenInterface implementation to use in this environment.
+ *
+ * If supplied, $targetAudience is used to set the "aud" on the resulting
+ * ID token.
+ *
+ * @param string $targetAudience The audience for the ID token.
+ * @param callable $httpHandler callback which delivers psr7 request
+ * @param array $cacheConfig configuration for the cache when it's present
+ * @param CacheItemPoolInterface $cache A cache implementation, may be
+ * provided if you have one already available for use.
+ * @return AuthTokenMiddleware
+ * @throws DomainException if no implementation can be obtained.
+ */
+ public static function getIdTokenMiddleware($targetAudience, ?callable $httpHandler = null, ?array $cacheConfig = null, ?CacheItemPoolInterface $cache = null)
+ {
+ $creds = self::getIdTokenCredentials($targetAudience, $httpHandler, $cacheConfig, $cache);
+ return new AuthTokenMiddleware($creds, $httpHandler);
+ }
+ /**
+ * Obtains an ProxyAuthTokenMiddleware which will fetch an ID token to use in the
+ * Authorization header. The middleware is configured with the default
+ * FetchAuthTokenInterface implementation to use in this environment.
+ *
+ * If supplied, $targetAudience is used to set the "aud" on the resulting
+ * ID token.
+ *
+ * @param string $targetAudience The audience for the ID token.
+ * @param callable $httpHandler callback which delivers psr7 request
+ * @param array $cacheConfig configuration for the cache when it's present
+ * @param CacheItemPoolInterface $cache A cache implementation, may be
+ * provided if you have one already available for use.
+ * @return ProxyAuthTokenMiddleware
+ * @throws DomainException if no implementation can be obtained.
+ */
+ public static function getProxyIdTokenMiddleware($targetAudience, ?callable $httpHandler = null, ?array $cacheConfig = null, ?CacheItemPoolInterface $cache = null)
+ {
+ $creds = self::getIdTokenCredentials($targetAudience, $httpHandler, $cacheConfig, $cache);
+ return new ProxyAuthTokenMiddleware($creds, $httpHandler);
+ }
+ /**
+ * Obtains the default FetchAuthTokenInterface implementation to use
+ * in this environment, configured with a $targetAudience for fetching an ID
+ * token.
+ *
+ * @param string $targetAudience The audience for the ID token.
+ * @param callable $httpHandler callback which delivers psr7 request
+ * @param array $cacheConfig configuration for the cache when it's present
+ * @param CacheItemPoolInterface $cache A cache implementation, may be
+ * provided if you have one already available for use.
+ * @return FetchAuthTokenInterface
+ * @throws DomainException if no implementation can be obtained.
+ * @throws InvalidArgumentException if JSON "type" key is invalid
+ */
+ public static function getIdTokenCredentials($targetAudience, ?callable $httpHandler = null, ?array $cacheConfig = null, ?CacheItemPoolInterface $cache = null)
+ {
+ $creds = null;
+ $jsonKey = CredentialsLoader::fromEnv() ?: CredentialsLoader::fromWellKnownFile();
+ if (!$httpHandler) {
+ if (!($client = HttpClientCache::getHttpClient())) {
+ $client = new Client();
+ HttpClientCache::setHttpClient($client);
+ }
+ $httpHandler = HttpHandlerFactory::build($client);
+ }
+ if (!\is_null($jsonKey)) {
+ if (!\array_key_exists('type', $jsonKey)) {
+ throw new \InvalidArgumentException('json key is missing the type field');
+ }
+ if ($jsonKey['type'] == 'authorized_user') {
+ throw new InvalidArgumentException('ID tokens are not supported for end user credentials');
+ }
+ if ($jsonKey['type'] != 'service_account') {
+ throw new InvalidArgumentException('invalid value in the type field');
+ }
+ $creds = new ServiceAccountCredentials(null, $jsonKey, null, $targetAudience);
+ } elseif (self::onGce($httpHandler, $cacheConfig, $cache)) {
+ $creds = new GCECredentials(null, null, $targetAudience);
+ $creds->setIsOnGce(\true);
+ // save the credentials a trip to the metadata server
+ }
+ if (\is_null($creds)) {
+ throw new DomainException(self::notFound());
+ }
+ if (!\is_null($cache)) {
+ $creds = new FetchAuthTokenCache($creds, $cacheConfig, $cache);
+ }
+ return $creds;
+ }
+ /**
+ * @return string
+ */
+ private static function notFound()
+ {
+ $msg = 'Your default credentials were not found. To set up ';
+ $msg .= 'Application Default Credentials, see ';
+ $msg .= 'https://cloud.google.com/docs/authentication/external/set-up-adc';
+ return $msg;
+ }
+ /**
+ * @param callable $httpHandler
+ * @param array $cacheConfig
+ * @param CacheItemPoolInterface $cache
+ * @return bool
+ */
+ private static function onGce(?callable $httpHandler = null, ?array $cacheConfig = null, ?CacheItemPoolInterface $cache = null)
+ {
+ $gceCacheConfig = [];
+ foreach (['lifetime', 'prefix'] as $key) {
+ if (isset($cacheConfig['gce_' . $key])) {
+ $gceCacheConfig[$key] = $cacheConfig['gce_' . $key];
+ }
+ }
+ return (new GCECache($gceCacheConfig, $cache))->onGce($httpHandler);
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Cache/InvalidArgumentException.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Cache/InvalidArgumentException.php
new file mode 100755
index 00000000..458ec5a9
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Cache/InvalidArgumentException.php
@@ -0,0 +1,23 @@
+key = $key;
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function getKey()
+ {
+ return $this->key;
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function get()
+ {
+ return $this->isHit() ? $this->value : null;
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function isHit()
+ {
+ if (!$this->isHit) {
+ return \false;
+ }
+ if ($this->expiration === null) {
+ return \true;
+ }
+ return $this->currentTime()->getTimestamp() < $this->expiration->getTimestamp();
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function set($value)
+ {
+ $this->isHit = \true;
+ $this->value = $value;
+ return $this;
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function expiresAt($expiration)
+ {
+ if ($this->isValidExpiration($expiration)) {
+ $this->expiration = $expiration;
+ return $this;
+ }
+ $error = \sprintf('Argument 1 passed to %s::expiresAt() must implement interface DateTimeInterface, %s given', \get_class($this), \gettype($expiration));
+ throw new TypeError($error);
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function expiresAfter($time)
+ {
+ if (\is_int($time)) {
+ $this->expiration = $this->currentTime()->add(new \DateInterval("PT{$time}S"));
+ } elseif ($time instanceof \DateInterval) {
+ $this->expiration = $this->currentTime()->add($time);
+ } elseif ($time === null) {
+ $this->expiration = $time;
+ } else {
+ $message = 'Argument 1 passed to %s::expiresAfter() must be an ' . 'instance of DateInterval or of the type integer, %s given';
+ $error = \sprintf($message, \get_class($this), \gettype($time));
+ throw new TypeError($error);
+ }
+ return $this;
+ }
+ /**
+ * Determines if an expiration is valid based on the rules defined by PSR6.
+ *
+ * @param mixed $expiration
+ * @return bool
+ */
+ private function isValidExpiration($expiration)
+ {
+ if ($expiration === null) {
+ return \true;
+ }
+ if ($expiration instanceof DateTimeInterface) {
+ return \true;
+ }
+ return \false;
+ }
+ /**
+ * @return DateTime
+ */
+ protected function currentTime()
+ {
+ return new DateTime('now', new DateTimeZone('UTC'));
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Cache/MemoryCacheItemPool.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Cache/MemoryCacheItemPool.php
new file mode 100755
index 00000000..b4360677
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Cache/MemoryCacheItemPool.php
@@ -0,0 +1,161 @@
+getItems([$key]));
+ // @phpstan-ignore-line
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return iterable
+ * A traversable collection of Cache Items keyed by the cache keys of
+ * each item. A Cache item will be returned for each key, even if that
+ * key is not found. However, if no keys are specified then an empty
+ * traversable MUST be returned instead.
+ */
+ public function getItems(array $keys = []) : iterable
+ {
+ $items = [];
+ $itemClass = \PHP_VERSION_ID >= 80000 ? TypedItem::class : Item::class;
+ foreach ($keys as $key) {
+ $items[$key] = $this->hasItem($key) ? clone $this->items[$key] : new $itemClass($key);
+ }
+ return $items;
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ * True if item exists in the cache, false otherwise.
+ */
+ public function hasItem($key) : bool
+ {
+ $this->isValidKey($key);
+ return isset($this->items[$key]) && $this->items[$key]->isHit();
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ * True if the pool was successfully cleared. False if there was an error.
+ */
+ public function clear() : bool
+ {
+ $this->items = [];
+ $this->deferredItems = [];
+ return \true;
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ * True if the item was successfully removed. False if there was an error.
+ */
+ public function deleteItem($key) : bool
+ {
+ return $this->deleteItems([$key]);
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ * True if the items were successfully removed. False if there was an error.
+ */
+ public function deleteItems(array $keys) : bool
+ {
+ \array_walk($keys, [$this, 'isValidKey']);
+ foreach ($keys as $key) {
+ unset($this->items[$key]);
+ }
+ return \true;
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ * True if the item was successfully persisted. False if there was an error.
+ */
+ public function save(CacheItemInterface $item) : bool
+ {
+ $this->items[$item->getKey()] = $item;
+ return \true;
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ * False if the item could not be queued or if a commit was attempted and failed. True otherwise.
+ */
+ public function saveDeferred(CacheItemInterface $item) : bool
+ {
+ $this->deferredItems[$item->getKey()] = $item;
+ return \true;
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ * True if all not-yet-saved items were successfully saved or there were none. False otherwise.
+ */
+ public function commit() : bool
+ {
+ foreach ($this->deferredItems as $item) {
+ $this->save($item);
+ }
+ $this->deferredItems = [];
+ return \true;
+ }
+ /**
+ * Determines if the provided key is valid.
+ *
+ * @param string $key
+ * @return bool
+ * @throws InvalidArgumentException
+ */
+ private function isValidKey($key)
+ {
+ $invalidCharacters = '{}()/\\\\@:';
+ if (!\is_string($key) || \preg_match("#[{$invalidCharacters}]#", $key)) {
+ throw new InvalidArgumentException('The provided key is not valid: ' . \var_export($key, \true));
+ }
+ return \true;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Cache/SysVCacheItemPool.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Cache/SysVCacheItemPool.php
new file mode 100755
index 00000000..41689f30
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Cache/SysVCacheItemPool.php
@@ -0,0 +1,207 @@
+
+ */
+ private $options;
+ /**
+ * @var bool
+ */
+ private $hasLoadedItems = \false;
+ /**
+ * Create a SystemV shared memory based CacheItemPool.
+ *
+ * @param array $options {
+ * [optional] Configuration options.
+ *
+ * @type int $variableKey The variable key for getting the data from the shared memory. **Defaults to** 1.
+ * @type string $proj The project identifier for ftok. This needs to be a one character string.
+ * **Defaults to** 'A'.
+ * @type int $memsize The memory size in bytes for shm_attach. **Defaults to** 10000.
+ * @type int $perm The permission for shm_attach. **Defaults to** 0600.
+ * }
+ */
+ public function __construct($options = [])
+ {
+ if (!\extension_loaded('sysvshm')) {
+ throw new \RuntimeException('sysvshm extension is required to use this ItemPool');
+ }
+ $this->options = $options + ['variableKey' => self::VAR_KEY, 'proj' => self::DEFAULT_PROJ, 'memsize' => self::DEFAULT_MEMSIZE, 'perm' => self::DEFAULT_PERM];
+ $this->items = [];
+ $this->deferredItems = [];
+ $this->sysvKey = \ftok(__FILE__, $this->options['proj']);
+ }
+ /**
+ * @param mixed $key
+ * @return CacheItemInterface
+ */
+ public function getItem($key) : CacheItemInterface
+ {
+ $this->loadItems();
+ return \current($this->getItems([$key]));
+ // @phpstan-ignore-line
+ }
+ /**
+ * @param array $keys
+ * @return iterable
+ */
+ public function getItems(array $keys = []) : iterable
+ {
+ $this->loadItems();
+ $items = [];
+ $itemClass = \PHP_VERSION_ID >= 80000 ? TypedItem::class : Item::class;
+ foreach ($keys as $key) {
+ $items[$key] = $this->hasItem($key) ? clone $this->items[$key] : new $itemClass($key);
+ }
+ return $items;
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function hasItem($key) : bool
+ {
+ $this->loadItems();
+ return isset($this->items[$key]) && $this->items[$key]->isHit();
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function clear() : bool
+ {
+ $this->items = [];
+ $this->deferredItems = [];
+ return $this->saveCurrentItems();
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function deleteItem($key) : bool
+ {
+ return $this->deleteItems([$key]);
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function deleteItems(array $keys) : bool
+ {
+ if (!$this->hasLoadedItems) {
+ $this->loadItems();
+ }
+ foreach ($keys as $key) {
+ unset($this->items[$key]);
+ }
+ return $this->saveCurrentItems();
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function save(CacheItemInterface $item) : bool
+ {
+ if (!$this->hasLoadedItems) {
+ $this->loadItems();
+ }
+ $this->items[$item->getKey()] = $item;
+ return $this->saveCurrentItems();
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function saveDeferred(CacheItemInterface $item) : bool
+ {
+ $this->deferredItems[$item->getKey()] = $item;
+ return \true;
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function commit() : bool
+ {
+ foreach ($this->deferredItems as $item) {
+ if ($this->save($item) === \false) {
+ return \false;
+ }
+ }
+ $this->deferredItems = [];
+ return \true;
+ }
+ /**
+ * Save the current items.
+ *
+ * @return bool true when success, false upon failure
+ */
+ private function saveCurrentItems()
+ {
+ $shmid = \shm_attach($this->sysvKey, $this->options['memsize'], $this->options['perm']);
+ if ($shmid !== \false) {
+ $ret = \shm_put_var($shmid, $this->options['variableKey'], $this->items);
+ \shm_detach($shmid);
+ return $ret;
+ }
+ return \false;
+ }
+ /**
+ * Load the items from the shared memory.
+ *
+ * @return bool true when success, false upon failure
+ */
+ private function loadItems()
+ {
+ $shmid = \shm_attach($this->sysvKey, $this->options['memsize'], $this->options['perm']);
+ if ($shmid !== \false) {
+ $data = @\shm_get_var($shmid, $this->options['variableKey']);
+ if (!empty($data)) {
+ $this->items = $data;
+ } else {
+ $this->items = [];
+ }
+ \shm_detach($shmid);
+ $this->hasLoadedItems = \true;
+ return \true;
+ }
+ return \false;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Cache/TypedItem.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Cache/TypedItem.php
new file mode 100755
index 00000000..6a687e52
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Cache/TypedItem.php
@@ -0,0 +1,142 @@
+key = $key;
+ $this->expiration = null;
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function getKey() : string
+ {
+ return $this->key;
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function get() : mixed
+ {
+ return $this->isHit() ? $this->value : null;
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function isHit() : bool
+ {
+ if (!$this->isHit) {
+ return \false;
+ }
+ if ($this->expiration === null) {
+ return \true;
+ }
+ return $this->currentTime()->getTimestamp() < $this->expiration->getTimestamp();
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function set(mixed $value) : static
+ {
+ $this->isHit = \true;
+ $this->value = $value;
+ return $this;
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function expiresAt($expiration) : static
+ {
+ if ($this->isValidExpiration($expiration)) {
+ $this->expiration = $expiration;
+ return $this;
+ }
+ $error = \sprintf('Argument 1 passed to %s::expiresAt() must implement interface DateTimeInterface, %s given', \get_class($this), \gettype($expiration));
+ throw new \TypeError($error);
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function expiresAfter($time) : static
+ {
+ if (\is_int($time)) {
+ $this->expiration = $this->currentTime()->add(new \DateInterval("PT{$time}S"));
+ } elseif ($time instanceof \DateInterval) {
+ $this->expiration = $this->currentTime()->add($time);
+ } elseif ($time === null) {
+ $this->expiration = $time;
+ } else {
+ $message = 'Argument 1 passed to %s::expiresAfter() must be an ' . 'instance of DateInterval or of the type integer, %s given';
+ $error = \sprintf($message, \get_class($this), \gettype($time));
+ throw new \TypeError($error);
+ }
+ return $this;
+ }
+ /**
+ * Determines if an expiration is valid based on the rules defined by PSR6.
+ *
+ * @param mixed $expiration
+ * @return bool
+ */
+ private function isValidExpiration($expiration)
+ {
+ if ($expiration === null) {
+ return \true;
+ }
+ // We test for two types here due to the fact the DateTimeInterface
+ // was not introduced until PHP 5.5. Checking for the DateTime type as
+ // well allows us to support 5.4.
+ if ($expiration instanceof \DateTimeInterface) {
+ return \true;
+ }
+ return \false;
+ }
+ /**
+ * @return \DateTime
+ */
+ protected function currentTime()
+ {
+ return new \DateTime('now', new \DateTimeZone('UTC'));
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/CacheTrait.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/CacheTrait.php
new file mode 100755
index 00000000..b13d9bdd
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/CacheTrait.php
@@ -0,0 +1,96 @@
+
+ */
+ private $cacheConfig;
+ /**
+ * @var ?CacheItemPoolInterface
+ */
+ private $cache;
+ /**
+ * Gets the cached value if it is present in the cache when that is
+ * available.
+ *
+ * @param mixed $k
+ *
+ * @return mixed
+ */
+ private function getCachedValue($k)
+ {
+ if (\is_null($this->cache)) {
+ return null;
+ }
+ $key = $this->getFullCacheKey($k);
+ if (\is_null($key)) {
+ return null;
+ }
+ $cacheItem = $this->cache->getItem($key);
+ if ($cacheItem->isHit()) {
+ return $cacheItem->get();
+ }
+ }
+ /**
+ * Saves the value in the cache when that is available.
+ *
+ * @param mixed $k
+ * @param mixed $v
+ * @return mixed
+ */
+ private function setCachedValue($k, $v)
+ {
+ if (\is_null($this->cache)) {
+ return null;
+ }
+ $key = $this->getFullCacheKey($k);
+ if (\is_null($key)) {
+ return null;
+ }
+ $cacheItem = $this->cache->getItem($key);
+ $cacheItem->set($v);
+ $cacheItem->expiresAfter($this->cacheConfig['lifetime']);
+ return $this->cache->save($cacheItem);
+ }
+ /**
+ * @param null|string $key
+ * @return null|string
+ */
+ private function getFullCacheKey($key)
+ {
+ if (\is_null($key)) {
+ return null;
+ }
+ $key = $this->cacheConfig['prefix'] . $key;
+ // ensure we do not have illegal characters
+ $key = \preg_replace('|[^a-zA-Z0-9_\\.!]|', '', $key);
+ // Hash keys if they exceed $maxKeyLength (defaults to 64)
+ if ($this->maxKeyLength && \strlen($key) > $this->maxKeyLength) {
+ $key = \substr(\hash('sha256', $key), 0, $this->maxKeyLength);
+ }
+ return $key;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/CredentialSource/AwsNativeSource.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/CredentialSource/AwsNativeSource.php
new file mode 100755
index 00000000..e10ec6d2
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/CredentialSource/AwsNativeSource.php
@@ -0,0 +1,270 @@
+audience = $audience;
+ $this->regionalCredVerificationUrl = $regionalCredVerificationUrl;
+ $this->regionUrl = $regionUrl;
+ $this->securityCredentialsUrl = $securityCredentialsUrl;
+ $this->imdsv2SessionTokenUrl = $imdsv2SessionTokenUrl;
+ }
+ public function fetchSubjectToken(?callable $httpHandler = null) : string
+ {
+ if (\is_null($httpHandler)) {
+ $httpHandler = HttpHandlerFactory::build(HttpClientCache::getHttpClient());
+ }
+ $headers = [];
+ if ($this->imdsv2SessionTokenUrl) {
+ $headers = ['X-aws-ec2-metadata-token' => self::getImdsV2SessionToken($this->imdsv2SessionTokenUrl, $httpHandler)];
+ }
+ if (!($signingVars = self::getSigningVarsFromEnv())) {
+ if (!$this->securityCredentialsUrl) {
+ throw new \LogicException('Unable to get credentials from ENV, and no security credentials URL provided');
+ }
+ $signingVars = self::getSigningVarsFromUrl($httpHandler, $this->securityCredentialsUrl, self::getRoleName($httpHandler, $this->securityCredentialsUrl, $headers), $headers);
+ }
+ if (!($region = self::getRegionFromEnv())) {
+ if (!$this->regionUrl) {
+ throw new \LogicException('Unable to get region from ENV, and no region URL provided');
+ }
+ $region = self::getRegionFromUrl($httpHandler, $this->regionUrl, $headers);
+ }
+ $url = \str_replace('{region}', $region, $this->regionalCredVerificationUrl);
+ $host = \parse_url($url)['host'] ?? '';
+ // From here we use the signing vars to create the signed request to receive a token
+ [$accessKeyId, $secretAccessKey, $securityToken] = $signingVars;
+ $headers = self::getSignedRequestHeaders($region, $host, $accessKeyId, $secretAccessKey, $securityToken);
+ // Inject x-goog-cloud-target-resource into header
+ $headers['x-goog-cloud-target-resource'] = $this->audience;
+ // Format headers as they're expected in the subject token
+ $formattedHeaders = \array_map(fn($k, $v) => ['key' => $k, 'value' => $v], \array_keys($headers), $headers);
+ $request = ['headers' => $formattedHeaders, 'method' => 'POST', 'url' => $url];
+ return \urlencode(\json_encode($request) ?: '');
+ }
+ /**
+ * @internal
+ */
+ public static function getImdsV2SessionToken(string $imdsV2Url, callable $httpHandler) : string
+ {
+ $headers = ['X-aws-ec2-metadata-token-ttl-seconds' => '21600'];
+ $request = new Request('PUT', $imdsV2Url, $headers);
+ $response = $httpHandler($request);
+ return (string) $response->getBody();
+ }
+ /**
+ * @see http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html
+ *
+ * @internal
+ *
+ * @return array
+ */
+ public static function getSignedRequestHeaders(string $region, string $host, string $accessKeyId, string $secretAccessKey, ?string $securityToken) : array
+ {
+ $service = 'sts';
+ # Create a date for headers and the credential string in ISO-8601 format
+ $amzdate = \gmdate('Ymd\\THis\\Z');
+ $datestamp = \gmdate('Ymd');
+ # Date w/o time, used in credential scope
+ # Create the canonical headers and signed headers. Header names
+ # must be trimmed and lowercase, and sorted in code point order from
+ # low to high. Note that there is a trailing \n.
+ $canonicalHeaders = \sprintf("host:%s\nx-amz-date:%s\n", $host, $amzdate);
+ if ($securityToken) {
+ $canonicalHeaders .= \sprintf("x-amz-security-token:%s\n", $securityToken);
+ }
+ # Step 5: Create the list of signed headers. This lists the headers
+ # in the canonicalHeaders list, delimited with ";" and in alpha order.
+ # Note: The request can include any headers; $canonicalHeaders and
+ # $signedHeaders lists those that you want to be included in the
+ # hash of the request. "Host" and "x-amz-date" are always required.
+ $signedHeaders = 'host;x-amz-date';
+ if ($securityToken) {
+ $signedHeaders .= ';x-amz-security-token';
+ }
+ # Step 6: Create payload hash (hash of the request body content). For GET
+ # requests, the payload is an empty string ("").
+ $payloadHash = \hash('sha256', '');
+ # Step 7: Combine elements to create canonical request
+ $canonicalRequest = \implode("\n", [
+ 'POST',
+ // method
+ '/',
+ // canonical URL
+ self::CRED_VERIFICATION_QUERY,
+ // query string
+ $canonicalHeaders,
+ $signedHeaders,
+ $payloadHash,
+ ]);
+ # ************* TASK 2: CREATE THE STRING TO SIGN*************
+ # Match the algorithm to the hashing algorithm you use, either SHA-1 or
+ # SHA-256 (recommended)
+ $algorithm = 'AWS4-HMAC-SHA256';
+ $scope = \implode('/', [$datestamp, $region, $service, 'aws4_request']);
+ $stringToSign = \implode("\n", [$algorithm, $amzdate, $scope, \hash('sha256', $canonicalRequest)]);
+ # ************* TASK 3: CALCULATE THE SIGNATURE *************
+ # Create the signing key using the function defined above.
+ // (done above)
+ $signingKey = self::getSignatureKey($secretAccessKey, $datestamp, $region, $service);
+ # Sign the string_to_sign using the signing_key
+ $signature = \bin2hex(self::hmacSign($signingKey, $stringToSign));
+ # ************* TASK 4: ADD SIGNING INFORMATION TO THE REQUEST *************
+ # The signing information can be either in a query string value or in
+ # a header named Authorization. This code shows how to use a header.
+ # Create authorization header and add to request headers
+ $authorizationHeader = \sprintf('%s Credential=%s/%s, SignedHeaders=%s, Signature=%s', $algorithm, $accessKeyId, $scope, $signedHeaders, $signature);
+ # The request can include any headers, but MUST include "host", "x-amz-date",
+ # and (for this scenario) "Authorization". "host" and "x-amz-date" must
+ # be included in the canonical_headers and signed_headers, as noted
+ # earlier. Order here is not significant.
+ $headers = ['host' => $host, 'x-amz-date' => $amzdate, 'Authorization' => $authorizationHeader];
+ if ($securityToken) {
+ $headers['x-amz-security-token'] = $securityToken;
+ }
+ return $headers;
+ }
+ /**
+ * @internal
+ */
+ public static function getRegionFromEnv() : ?string
+ {
+ $region = \getenv('AWS_REGION');
+ if (empty($region)) {
+ $region = \getenv('AWS_DEFAULT_REGION');
+ }
+ return $region ?: null;
+ }
+ /**
+ * @internal
+ *
+ * @param callable $httpHandler
+ * @param string $regionUrl
+ * @param array $headers Request headers to send in with the request.
+ */
+ public static function getRegionFromUrl(callable $httpHandler, string $regionUrl, array $headers) : string
+ {
+ // get the region/zone from the region URL
+ $regionRequest = new Request('GET', $regionUrl, $headers);
+ $regionResponse = $httpHandler($regionRequest);
+ // Remove last character. For example, if us-east-2b is returned,
+ // the region would be us-east-2.
+ return \substr((string) $regionResponse->getBody(), 0, -1);
+ }
+ /**
+ * @internal
+ *
+ * @param callable $httpHandler
+ * @param string $securityCredentialsUrl
+ * @param array $headers Request headers to send in with the request.
+ */
+ public static function getRoleName(callable $httpHandler, string $securityCredentialsUrl, array $headers) : string
+ {
+ // Get the AWS role name
+ $roleRequest = new Request('GET', $securityCredentialsUrl, $headers);
+ $roleResponse = $httpHandler($roleRequest);
+ $roleName = (string) $roleResponse->getBody();
+ return $roleName;
+ }
+ /**
+ * @internal
+ *
+ * @param callable $httpHandler
+ * @param string $securityCredentialsUrl
+ * @param array $headers Request headers to send in with the request.
+ * @return array{string, string, ?string}
+ */
+ public static function getSigningVarsFromUrl(callable $httpHandler, string $securityCredentialsUrl, string $roleName, array $headers) : array
+ {
+ // Get the AWS credentials
+ $credsRequest = new Request('GET', $securityCredentialsUrl . '/' . $roleName, $headers);
+ $credsResponse = $httpHandler($credsRequest);
+ $awsCreds = \json_decode((string) $credsResponse->getBody(), \true);
+ return [
+ $awsCreds['AccessKeyId'],
+ // accessKeyId
+ $awsCreds['SecretAccessKey'],
+ // secretAccessKey
+ $awsCreds['Token'],
+ ];
+ }
+ /**
+ * @internal
+ *
+ * @return array{string, string, ?string}
+ */
+ public static function getSigningVarsFromEnv() : ?array
+ {
+ $accessKeyId = \getenv('AWS_ACCESS_KEY_ID');
+ $secretAccessKey = \getenv('AWS_SECRET_ACCESS_KEY');
+ if ($accessKeyId && $secretAccessKey) {
+ return [$accessKeyId, $secretAccessKey, \getenv('AWS_SESSION_TOKEN') ?: null];
+ }
+ return null;
+ }
+ /**
+ * Return HMAC hash in binary string
+ */
+ private static function hmacSign(string $key, string $msg) : string
+ {
+ return \hash_hmac('sha256', self::utf8Encode($msg), $key, \true);
+ }
+ /**
+ * @TODO add a fallback when mbstring is not available
+ */
+ private static function utf8Encode(string $string) : string
+ {
+ return \mb_convert_encoding($string, 'UTF-8', 'ISO-8859-1');
+ }
+ private static function getSignatureKey(string $key, string $dateStamp, string $regionName, string $serviceName) : string
+ {
+ $kDate = self::hmacSign(self::utf8Encode('AWS4' . $key), $dateStamp);
+ $kRegion = self::hmacSign($kDate, $regionName);
+ $kService = self::hmacSign($kRegion, $serviceName);
+ $kSigning = self::hmacSign($kService, 'aws4_request');
+ return $kSigning;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/CredentialSource/FileSource.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/CredentialSource/FileSource.php
new file mode 100755
index 00000000..8a29dc85
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/CredentialSource/FileSource.php
@@ -0,0 +1,60 @@
+file = $file;
+ if ($format === 'json' && \is_null($subjectTokenFieldName)) {
+ throw new InvalidArgumentException('subject_token_field_name must be set when format is JSON');
+ }
+ $this->format = $format;
+ $this->subjectTokenFieldName = $subjectTokenFieldName;
+ }
+ public function fetchSubjectToken(?callable $httpHandler = null) : string
+ {
+ $contents = \file_get_contents($this->file);
+ if ($this->format === 'json') {
+ if (!($json = \json_decode((string) $contents, \true))) {
+ throw new UnexpectedValueException('Unable to decode JSON file');
+ }
+ if (!isset($json[$this->subjectTokenFieldName])) {
+ throw new UnexpectedValueException('subject_token_field_name not found in JSON file');
+ }
+ $contents = $json[$this->subjectTokenFieldName];
+ }
+ return $contents;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/CredentialSource/UrlSource.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/CredentialSource/UrlSource.php
new file mode 100755
index 00000000..83d8d75b
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/CredentialSource/UrlSource.php
@@ -0,0 +1,74 @@
+
+ */
+ private ?array $headers;
+ /**
+ * @param string $url The URL to fetch the subject token from.
+ * @param string $format The format of the token in the response. Can be null or "json".
+ * @param string $subjectTokenFieldName The name of the field containing the token in the response. This is required
+ * when format is "json".
+ * @param array $headers Request headers to send in with the request to the URL.
+ */
+ public function __construct(string $url, ?string $format = null, ?string $subjectTokenFieldName = null, ?array $headers = null)
+ {
+ $this->url = $url;
+ if ($format === 'json' && \is_null($subjectTokenFieldName)) {
+ throw new InvalidArgumentException('subject_token_field_name must be set when format is JSON');
+ }
+ $this->format = $format;
+ $this->subjectTokenFieldName = $subjectTokenFieldName;
+ $this->headers = $headers;
+ }
+ public function fetchSubjectToken(?callable $httpHandler = null) : string
+ {
+ if (\is_null($httpHandler)) {
+ $httpHandler = HttpHandlerFactory::build(HttpClientCache::getHttpClient());
+ }
+ $request = new Request('GET', $this->url, $this->headers ?: []);
+ $response = $httpHandler($request);
+ $body = (string) $response->getBody();
+ if ($this->format === 'json') {
+ if (!($json = \json_decode((string) $body, \true))) {
+ throw new UnexpectedValueException('Unable to decode JSON response');
+ }
+ if (!isset($json[$this->subjectTokenFieldName])) {
+ throw new UnexpectedValueException('subject_token_field_name not found in JSON file');
+ }
+ $body = $json[$this->subjectTokenFieldName];
+ }
+ return $body;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Credentials/AppIdentityCredentials.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Credentials/AppIdentityCredentials.php
new file mode 100755
index 00000000..d5de0c30
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Credentials/AppIdentityCredentials.php
@@ -0,0 +1,209 @@
+push($middleware);
+ *
+ * $client = new Client([
+ * 'handler' => $stack,
+ * 'base_uri' => 'https://www.googleapis.com/books/v1',
+ * 'auth' => 'google_auth'
+ * ]);
+ *
+ * $res = $client->get('volumes?q=Henry+David+Thoreau&country=US');
+ * ```
+ */
+class AppIdentityCredentials extends CredentialsLoader implements SignBlobInterface, ProjectIdProviderInterface
+{
+ /**
+ * Result of fetchAuthToken.
+ *
+ * @var array
+ */
+ protected $lastReceivedToken;
+ /**
+ * Array of OAuth2 scopes to be requested.
+ *
+ * @var string[]
+ */
+ private $scope;
+ /**
+ * @var string
+ */
+ private $clientName;
+ /**
+ * @param string|string[] $scope One or more scopes.
+ */
+ public function __construct($scope = [])
+ {
+ $this->scope = \is_array($scope) ? $scope : \explode(' ', (string) $scope);
+ }
+ /**
+ * Determines if this an App Engine instance, by accessing the
+ * SERVER_SOFTWARE environment variable (prod) or the APPENGINE_RUNTIME
+ * environment variable (dev).
+ *
+ * @return bool true if this an App Engine Instance, false otherwise
+ */
+ public static function onAppEngine()
+ {
+ $appEngineProduction = isset($_SERVER['SERVER_SOFTWARE']) && 0 === \strpos($_SERVER['SERVER_SOFTWARE'], 'Google App Engine');
+ if ($appEngineProduction) {
+ return \true;
+ }
+ $appEngineDevAppServer = isset($_SERVER['APPENGINE_RUNTIME']) && $_SERVER['APPENGINE_RUNTIME'] == 'php';
+ if ($appEngineDevAppServer) {
+ return \true;
+ }
+ return \false;
+ }
+ /**
+ * Implements FetchAuthTokenInterface#fetchAuthToken.
+ *
+ * Fetches the auth tokens using the AppIdentityService if available.
+ * As the AppIdentityService uses protobufs to fetch the access token,
+ * the GuzzleHttp\ClientInterface instance passed in will not be used.
+ *
+ * @param callable $httpHandler callback which delivers psr7 request
+ * @return array {
+ * A set of auth related metadata, containing the following
+ *
+ * @type string $access_token
+ * @type string $expiration_time
+ * }
+ */
+ public function fetchAuthToken(?callable $httpHandler = null)
+ {
+ try {
+ $this->checkAppEngineContext();
+ } catch (\Exception $e) {
+ return [];
+ }
+ /** @phpstan-ignore-next-line */
+ $token = AppIdentityService::getAccessToken($this->scope);
+ $this->lastReceivedToken = $token;
+ return $token;
+ }
+ /**
+ * Sign a string using AppIdentityService.
+ *
+ * @param string $stringToSign The string to sign.
+ * @param bool $forceOpenSsl [optional] Does not apply to this credentials
+ * type.
+ * @return string The signature, base64-encoded.
+ * @throws \Exception If AppEngine SDK or mock is not available.
+ */
+ public function signBlob($stringToSign, $forceOpenSsl = \false)
+ {
+ $this->checkAppEngineContext();
+ /** @phpstan-ignore-next-line */
+ return \base64_encode(AppIdentityService::signForApp($stringToSign)['signature']);
+ }
+ /**
+ * Get the project ID from AppIdentityService.
+ *
+ * Returns null if AppIdentityService is unavailable.
+ *
+ * @param callable $httpHandler Not used by this type.
+ * @return string|null
+ */
+ public function getProjectId(?callable $httpHandler = null)
+ {
+ try {
+ $this->checkAppEngineContext();
+ } catch (\Exception $e) {
+ return null;
+ }
+ /** @phpstan-ignore-next-line */
+ return AppIdentityService::getApplicationId();
+ }
+ /**
+ * Get the client name from AppIdentityService.
+ *
+ * Subsequent calls to this method will return a cached value.
+ *
+ * @param callable $httpHandler Not used in this implementation.
+ * @return string
+ * @throws \Exception If AppEngine SDK or mock is not available.
+ */
+ public function getClientName(?callable $httpHandler = null)
+ {
+ $this->checkAppEngineContext();
+ if (!$this->clientName) {
+ /** @phpstan-ignore-next-line */
+ $this->clientName = AppIdentityService::getServiceAccountName();
+ }
+ return $this->clientName;
+ }
+ /**
+ * @return array{access_token:string,expires_at:int}|null
+ */
+ public function getLastReceivedToken()
+ {
+ if ($this->lastReceivedToken) {
+ return ['access_token' => $this->lastReceivedToken['access_token'], 'expires_at' => $this->lastReceivedToken['expiration_time']];
+ }
+ return null;
+ }
+ /**
+ * Caching is handled by the underlying AppIdentityService, return empty string
+ * to prevent caching.
+ *
+ * @return string
+ */
+ public function getCacheKey()
+ {
+ return '';
+ }
+ /**
+ * @return void
+ */
+ private function checkAppEngineContext()
+ {
+ if (!self::onAppEngine() || !\class_exists('WPMailSMTP\\Vendor\\google\\appengine\\api\\app_identity\\AppIdentityService')) {
+ throw new \Exception('This class must be run in App Engine, or you must include the AppIdentityService ' . 'mock class defined in tests/mocks/AppIdentityService.php');
+ }
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Credentials/ExternalAccountCredentials.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Credentials/ExternalAccountCredentials.php
new file mode 100755
index 00000000..c1cb38fd
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Credentials/ExternalAccountCredentials.php
@@ -0,0 +1,229 @@
+ $jsonKey JSON credentials as an associative array.
+ */
+ public function __construct($scope, array $jsonKey)
+ {
+ if (!\array_key_exists('type', $jsonKey)) {
+ throw new InvalidArgumentException('json key is missing the type field');
+ }
+ if ($jsonKey['type'] !== self::EXTERNAL_ACCOUNT_TYPE) {
+ throw new InvalidArgumentException(\sprintf('expected "%s" type but received "%s"', self::EXTERNAL_ACCOUNT_TYPE, $jsonKey['type']));
+ }
+ if (!\array_key_exists('token_url', $jsonKey)) {
+ throw new InvalidArgumentException('json key is missing the token_url field');
+ }
+ if (!\array_key_exists('audience', $jsonKey)) {
+ throw new InvalidArgumentException('json key is missing the audience field');
+ }
+ if (!\array_key_exists('subject_token_type', $jsonKey)) {
+ throw new InvalidArgumentException('json key is missing the subject_token_type field');
+ }
+ if (!\array_key_exists('credential_source', $jsonKey)) {
+ throw new InvalidArgumentException('json key is missing the credential_source field');
+ }
+ if (\array_key_exists('service_account_impersonation_url', $jsonKey)) {
+ $this->serviceAccountImpersonationUrl = $jsonKey['service_account_impersonation_url'];
+ }
+ $this->quotaProject = $jsonKey['quota_project_id'] ?? null;
+ $this->workforcePoolUserProject = $jsonKey['workforce_pool_user_project'] ?? null;
+ $this->universeDomain = $jsonKey['universe_domain'] ?? GetUniverseDomainInterface::DEFAULT_UNIVERSE_DOMAIN;
+ $this->auth = new OAuth2(['tokenCredentialUri' => $jsonKey['token_url'], 'audience' => $jsonKey['audience'], 'scope' => $scope, 'subjectTokenType' => $jsonKey['subject_token_type'], 'subjectTokenFetcher' => self::buildCredentialSource($jsonKey), 'additionalOptions' => $this->workforcePoolUserProject ? ['userProject' => $this->workforcePoolUserProject] : []]);
+ if (!$this->isWorkforcePool() && $this->workforcePoolUserProject) {
+ throw new InvalidArgumentException('workforce_pool_user_project should not be set for non-workforce pool credentials.');
+ }
+ }
+ /**
+ * @param array $jsonKey
+ */
+ private static function buildCredentialSource(array $jsonKey) : ExternalAccountCredentialSourceInterface
+ {
+ $credentialSource = $jsonKey['credential_source'];
+ if (isset($credentialSource['file'])) {
+ return new FileSource($credentialSource['file'], $credentialSource['format']['type'] ?? null, $credentialSource['format']['subject_token_field_name'] ?? null);
+ }
+ if (isset($credentialSource['environment_id']) && 1 === \preg_match('/^aws(\\d+)$/', $credentialSource['environment_id'], $matches)) {
+ if ($matches[1] !== '1') {
+ throw new InvalidArgumentException("aws version \"{$matches[1]}\" is not supported in the current build.");
+ }
+ if (!\array_key_exists('regional_cred_verification_url', $credentialSource)) {
+ throw new InvalidArgumentException('The regional_cred_verification_url field is required for aws1 credential source.');
+ }
+ if (!\array_key_exists('audience', $jsonKey)) {
+ throw new InvalidArgumentException('aws1 credential source requires an audience to be set in the JSON file.');
+ }
+ return new AwsNativeSource(
+ $jsonKey['audience'],
+ $credentialSource['regional_cred_verification_url'],
+ // $regionalCredVerificationUrl
+ $credentialSource['region_url'] ?? null,
+ // $regionUrl
+ $credentialSource['url'] ?? null,
+ // $securityCredentialsUrl
+ $credentialSource['imdsv2_session_token_url'] ?? null
+ );
+ }
+ if (isset($credentialSource['url'])) {
+ return new UrlSource($credentialSource['url'], $credentialSource['format']['type'] ?? null, $credentialSource['format']['subject_token_field_name'] ?? null, $credentialSource['headers'] ?? null);
+ }
+ throw new InvalidArgumentException('Unable to determine credential source from json key.');
+ }
+ /**
+ * @param string $stsToken
+ * @param callable $httpHandler
+ *
+ * @return array {
+ * A set of auth related metadata, containing the following
+ *
+ * @type string $access_token
+ * @type int $expires_at
+ * }
+ */
+ private function getImpersonatedAccessToken(string $stsToken, ?callable $httpHandler = null) : array
+ {
+ if (!isset($this->serviceAccountImpersonationUrl)) {
+ throw new InvalidArgumentException('service_account_impersonation_url must be set in JSON credentials.');
+ }
+ $request = new Request('POST', $this->serviceAccountImpersonationUrl, ['Content-Type' => 'application/json', 'Authorization' => 'Bearer ' . $stsToken], (string) \json_encode(['lifetime' => \sprintf('%ss', OAuth2::DEFAULT_EXPIRY_SECONDS), 'scope' => \explode(' ', $this->auth->getScope())]));
+ if (\is_null($httpHandler)) {
+ $httpHandler = HttpHandlerFactory::build(HttpClientCache::getHttpClient());
+ }
+ $response = $httpHandler($request);
+ $body = \json_decode((string) $response->getBody(), \true);
+ return ['access_token' => $body['accessToken'], 'expires_at' => \strtotime($body['expireTime'])];
+ }
+ /**
+ * @param callable $httpHandler
+ *
+ * @return array {
+ * A set of auth related metadata, containing the following
+ *
+ * @type string $access_token
+ * @type int $expires_at (impersonated service accounts only)
+ * @type int $expires_in (identity pool only)
+ * @type string $issued_token_type (identity pool only)
+ * @type string $token_type (identity pool only)
+ * }
+ */
+ public function fetchAuthToken(?callable $httpHandler = null)
+ {
+ $stsToken = $this->auth->fetchAuthToken($httpHandler);
+ if (isset($this->serviceAccountImpersonationUrl)) {
+ return $this->getImpersonatedAccessToken($stsToken['access_token'], $httpHandler);
+ }
+ return $stsToken;
+ }
+ public function getCacheKey()
+ {
+ return $this->auth->getCacheKey();
+ }
+ public function getLastReceivedToken()
+ {
+ return $this->auth->getLastReceivedToken();
+ }
+ /**
+ * Get the quota project used for this API request
+ *
+ * @return string|null
+ */
+ public function getQuotaProject()
+ {
+ return $this->quotaProject;
+ }
+ /**
+ * Get the universe domain used for this API request
+ *
+ * @return string
+ */
+ public function getUniverseDomain() : string
+ {
+ return $this->universeDomain;
+ }
+ /**
+ * Get the project ID.
+ *
+ * @param callable $httpHandler Callback which delivers psr7 request
+ * @param string $accessToken The access token to use to sign the blob. If
+ * provided, saves a call to the metadata server for a new access
+ * token. **Defaults to** `null`.
+ * @return string|null
+ */
+ public function getProjectId(?callable $httpHandler = null, ?string $accessToken = null)
+ {
+ if (isset($this->projectId)) {
+ return $this->projectId;
+ }
+ $projectNumber = $this->getProjectNumber() ?: $this->workforcePoolUserProject;
+ if (!$projectNumber) {
+ return null;
+ }
+ if (\is_null($httpHandler)) {
+ $httpHandler = HttpHandlerFactory::build(HttpClientCache::getHttpClient());
+ }
+ $url = \str_replace('UNIVERSE_DOMAIN', $this->getUniverseDomain(), \sprintf(self::CLOUD_RESOURCE_MANAGER_URL, $projectNumber));
+ if (\is_null($accessToken)) {
+ $accessToken = $this->fetchAuthToken($httpHandler)['access_token'];
+ }
+ $request = new Request('GET', $url, ['authorization' => 'Bearer ' . $accessToken]);
+ $response = $httpHandler($request);
+ $body = \json_decode((string) $response->getBody(), \true);
+ return $this->projectId = $body['projectId'];
+ }
+ private function getProjectNumber() : ?string
+ {
+ $parts = \explode('/', $this->auth->getAudience());
+ $i = \array_search('projects', $parts);
+ return $parts[$i + 1] ?? null;
+ }
+ private function isWorkforcePool() : bool
+ {
+ $regex = '#//iam\\.googleapis\\.com/locations/[^/]+/workforcePools/#';
+ return \preg_match($regex, $this->auth->getAudience()) === 1;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Credentials/GCECredentials.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Credentials/GCECredentials.php
new file mode 100755
index 00000000..8d7b5f08
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Credentials/GCECredentials.php
@@ -0,0 +1,493 @@
+push($middleware);
+ *
+ * $client = new Client([
+ * 'handler' => $stack,
+ * 'base_uri' => 'https://www.googleapis.com/taskqueue/v1beta2/projects/',
+ * 'auth' => 'google_auth'
+ * ]);
+ *
+ * $res = $client->get('myproject/taskqueues/myqueue');
+ */
+class GCECredentials extends CredentialsLoader implements SignBlobInterface, ProjectIdProviderInterface, GetQuotaProjectInterface
+{
+ use IamSignerTrait;
+ // phpcs:disable
+ const cacheKey = 'GOOGLE_AUTH_PHP_GCE';
+ // phpcs:enable
+ /**
+ * The metadata IP address on appengine instances.
+ *
+ * The IP is used instead of the domain 'metadata' to avoid slow responses
+ * when not on Compute Engine.
+ */
+ const METADATA_IP = '169.254.169.254';
+ /**
+ * The metadata path of the default token.
+ */
+ const TOKEN_URI_PATH = 'v1/instance/service-accounts/default/token';
+ /**
+ * The metadata path of the default id token.
+ */
+ const ID_TOKEN_URI_PATH = 'v1/instance/service-accounts/default/identity';
+ /**
+ * The metadata path of the client ID.
+ */
+ const CLIENT_ID_URI_PATH = 'v1/instance/service-accounts/default/email';
+ /**
+ * The metadata path of the project ID.
+ */
+ const PROJECT_ID_URI_PATH = 'v1/project/project-id';
+ /**
+ * The metadata path of the project ID.
+ */
+ const UNIVERSE_DOMAIN_URI_PATH = 'v1/universe/universe_domain';
+ /**
+ * The header whose presence indicates GCE presence.
+ */
+ const FLAVOR_HEADER = 'Metadata-Flavor';
+ /**
+ * The Linux file which contains the product name.
+ */
+ private const GKE_PRODUCT_NAME_FILE = '/sys/class/dmi/id/product_name';
+ /**
+ * Note: the explicit `timeout` and `tries` below is a workaround. The underlying
+ * issue is that resolving an unknown host on some networks will take
+ * 20-30 seconds; making this timeout short fixes the issue, but
+ * could lead to false negatives in the event that we are on GCE, but
+ * the metadata resolution was particularly slow. The latter case is
+ * "unlikely" since the expected 4-nines time is about 0.5 seconds.
+ * This allows us to limit the total ping maximum timeout to 1.5 seconds
+ * for developer desktop scenarios.
+ */
+ const MAX_COMPUTE_PING_TRIES = 3;
+ const COMPUTE_PING_CONNECTION_TIMEOUT_S = 0.5;
+ /**
+ * Flag used to ensure that the onGCE test is only done once;.
+ *
+ * @var bool
+ */
+ private $hasCheckedOnGce = \false;
+ /**
+ * Flag that stores the value of the onGCE check.
+ *
+ * @var bool
+ */
+ private $isOnGce = \false;
+ /**
+ * Result of fetchAuthToken.
+ *
+ * @var array
+ */
+ protected $lastReceivedToken;
+ /**
+ * @var string|null
+ */
+ private $clientName;
+ /**
+ * @var string|null
+ */
+ private $projectId;
+ /**
+ * @var string
+ */
+ private $tokenUri;
+ /**
+ * @var string
+ */
+ private $targetAudience;
+ /**
+ * @var string|null
+ */
+ private $quotaProject;
+ /**
+ * @var string|null
+ */
+ private $serviceAccountIdentity;
+ /**
+ * @var string
+ */
+ private ?string $universeDomain;
+ /**
+ * @param Iam $iam [optional] An IAM instance.
+ * @param string|string[] $scope [optional] the scope of the access request,
+ * expressed either as an array or as a space-delimited string.
+ * @param string $targetAudience [optional] The audience for the ID token.
+ * @param string $quotaProject [optional] Specifies a project to bill for access
+ * charges associated with the request.
+ * @param string $serviceAccountIdentity [optional] Specify a service
+ * account identity name to use instead of "default".
+ * @param string $universeDomain [optional] Specify a universe domain to use
+ * instead of fetching one from the metadata server.
+ */
+ public function __construct(?Iam $iam = null, $scope = null, $targetAudience = null, $quotaProject = null, $serviceAccountIdentity = null, ?string $universeDomain = null)
+ {
+ $this->iam = $iam;
+ if ($scope && $targetAudience) {
+ throw new InvalidArgumentException('Scope and targetAudience cannot both be supplied');
+ }
+ $tokenUri = self::getTokenUri($serviceAccountIdentity);
+ if ($scope) {
+ if (\is_string($scope)) {
+ $scope = \explode(' ', $scope);
+ }
+ $scope = \implode(',', $scope);
+ $tokenUri = $tokenUri . '?scopes=' . $scope;
+ } elseif ($targetAudience) {
+ $tokenUri = self::getIdTokenUri($serviceAccountIdentity);
+ $tokenUri = $tokenUri . '?audience=' . $targetAudience;
+ $this->targetAudience = $targetAudience;
+ }
+ $this->tokenUri = $tokenUri;
+ $this->quotaProject = $quotaProject;
+ $this->serviceAccountIdentity = $serviceAccountIdentity;
+ $this->universeDomain = $universeDomain;
+ }
+ /**
+ * The full uri for accessing the default token.
+ *
+ * @param string $serviceAccountIdentity [optional] Specify a service
+ * account identity name to use instead of "default".
+ * @return string
+ */
+ public static function getTokenUri($serviceAccountIdentity = null)
+ {
+ $base = 'http://' . self::METADATA_IP . '/computeMetadata/';
+ $base .= self::TOKEN_URI_PATH;
+ if ($serviceAccountIdentity) {
+ return \str_replace('/default/', '/' . $serviceAccountIdentity . '/', $base);
+ }
+ return $base;
+ }
+ /**
+ * The full uri for accessing the default service account.
+ *
+ * @param string $serviceAccountIdentity [optional] Specify a service
+ * account identity name to use instead of "default".
+ * @return string
+ */
+ public static function getClientNameUri($serviceAccountIdentity = null)
+ {
+ $base = 'http://' . self::METADATA_IP . '/computeMetadata/';
+ $base .= self::CLIENT_ID_URI_PATH;
+ if ($serviceAccountIdentity) {
+ return \str_replace('/default/', '/' . $serviceAccountIdentity . '/', $base);
+ }
+ return $base;
+ }
+ /**
+ * The full uri for accesesing the default identity token.
+ *
+ * @param string $serviceAccountIdentity [optional] Specify a service
+ * account identity name to use instead of "default".
+ * @return string
+ */
+ private static function getIdTokenUri($serviceAccountIdentity = null)
+ {
+ $base = 'http://' . self::METADATA_IP . '/computeMetadata/';
+ $base .= self::ID_TOKEN_URI_PATH;
+ if ($serviceAccountIdentity) {
+ return \str_replace('/default/', '/' . $serviceAccountIdentity . '/', $base);
+ }
+ return $base;
+ }
+ /**
+ * The full uri for accessing the default project ID.
+ *
+ * @return string
+ */
+ private static function getProjectIdUri()
+ {
+ $base = 'http://' . self::METADATA_IP . '/computeMetadata/';
+ return $base . self::PROJECT_ID_URI_PATH;
+ }
+ /**
+ * The full uri for accessing the default universe domain.
+ *
+ * @return string
+ */
+ private static function getUniverseDomainUri()
+ {
+ $base = 'http://' . self::METADATA_IP . '/computeMetadata/';
+ return $base . self::UNIVERSE_DOMAIN_URI_PATH;
+ }
+ /**
+ * Determines if this an App Engine Flexible instance, by accessing the
+ * GAE_INSTANCE environment variable.
+ *
+ * @return bool true if this an App Engine Flexible Instance, false otherwise
+ */
+ public static function onAppEngineFlexible()
+ {
+ return \substr((string) \getenv('GAE_INSTANCE'), 0, 4) === 'aef-';
+ }
+ /**
+ * Determines if this a GCE instance, by accessing the expected metadata
+ * host.
+ * If $httpHandler is not specified a the default HttpHandler is used.
+ *
+ * @param callable $httpHandler callback which delivers psr7 request
+ * @return bool True if this a GCEInstance, false otherwise
+ */
+ public static function onGce(?callable $httpHandler = null)
+ {
+ $httpHandler = $httpHandler ?: HttpHandlerFactory::build(HttpClientCache::getHttpClient());
+ $checkUri = 'http://' . self::METADATA_IP;
+ for ($i = 1; $i <= self::MAX_COMPUTE_PING_TRIES; $i++) {
+ try {
+ // Comment from: oauth2client/client.py
+ //
+ // Note: the explicit `timeout` below is a workaround. The underlying
+ // issue is that resolving an unknown host on some networks will take
+ // 20-30 seconds; making this timeout short fixes the issue, but
+ // could lead to false negatives in the event that we are on GCE, but
+ // the metadata resolution was particularly slow. The latter case is
+ // "unlikely".
+ $resp = $httpHandler(new Request('GET', $checkUri, [self::FLAVOR_HEADER => 'Google']), ['timeout' => self::COMPUTE_PING_CONNECTION_TIMEOUT_S]);
+ return $resp->getHeaderLine(self::FLAVOR_HEADER) == 'Google';
+ } catch (ClientException $e) {
+ } catch (ServerException $e) {
+ } catch (RequestException $e) {
+ } catch (ConnectException $e) {
+ }
+ }
+ if (\PHP_OS === 'Windows') {
+ // @TODO: implement GCE residency detection on Windows
+ return \false;
+ }
+ // Detect GCE residency on Linux
+ return self::detectResidencyLinux(self::GKE_PRODUCT_NAME_FILE);
+ }
+ private static function detectResidencyLinux(string $productNameFile) : bool
+ {
+ if (\file_exists($productNameFile)) {
+ $productName = \trim((string) \file_get_contents($productNameFile));
+ return 0 === \strpos($productName, 'Google');
+ }
+ return \false;
+ }
+ /**
+ * Implements FetchAuthTokenInterface#fetchAuthToken.
+ *
+ * Fetches the auth tokens from the GCE metadata host if it is available.
+ * If $httpHandler is not specified a the default HttpHandler is used.
+ *
+ * @param callable $httpHandler callback which delivers psr7 request
+ *
+ * @return array {
+ * A set of auth related metadata, based on the token type.
+ *
+ * @type string $access_token for access tokens
+ * @type int $expires_in for access tokens
+ * @type string $token_type for access tokens
+ * @type string $id_token for ID tokens
+ * }
+ * @throws \Exception
+ */
+ public function fetchAuthToken(?callable $httpHandler = null)
+ {
+ $httpHandler = $httpHandler ?: HttpHandlerFactory::build(HttpClientCache::getHttpClient());
+ if (!$this->hasCheckedOnGce) {
+ $this->isOnGce = self::onGce($httpHandler);
+ $this->hasCheckedOnGce = \true;
+ }
+ if (!$this->isOnGce) {
+ return [];
+ // return an empty array with no access token
+ }
+ $response = $this->getFromMetadata($httpHandler, $this->tokenUri);
+ if ($this->targetAudience) {
+ return $this->lastReceivedToken = ['id_token' => $response];
+ }
+ if (null === ($json = \json_decode($response, \true))) {
+ throw new \Exception('Invalid JSON response');
+ }
+ $json['expires_at'] = \time() + $json['expires_in'];
+ // store this so we can retrieve it later
+ $this->lastReceivedToken = $json;
+ return $json;
+ }
+ /**
+ * @return string
+ */
+ public function getCacheKey()
+ {
+ return self::cacheKey;
+ }
+ /**
+ * @return array|null
+ */
+ public function getLastReceivedToken()
+ {
+ if ($this->lastReceivedToken) {
+ if (\array_key_exists('id_token', $this->lastReceivedToken)) {
+ return $this->lastReceivedToken;
+ }
+ return ['access_token' => $this->lastReceivedToken['access_token'], 'expires_at' => $this->lastReceivedToken['expires_at']];
+ }
+ return null;
+ }
+ /**
+ * Get the client name from GCE metadata.
+ *
+ * Subsequent calls will return a cached value.
+ *
+ * @param callable $httpHandler callback which delivers psr7 request
+ * @return string
+ */
+ public function getClientName(?callable $httpHandler = null)
+ {
+ if ($this->clientName) {
+ return $this->clientName;
+ }
+ $httpHandler = $httpHandler ?: HttpHandlerFactory::build(HttpClientCache::getHttpClient());
+ if (!$this->hasCheckedOnGce) {
+ $this->isOnGce = self::onGce($httpHandler);
+ $this->hasCheckedOnGce = \true;
+ }
+ if (!$this->isOnGce) {
+ return '';
+ }
+ $this->clientName = $this->getFromMetadata($httpHandler, self::getClientNameUri($this->serviceAccountIdentity));
+ return $this->clientName;
+ }
+ /**
+ * Fetch the default Project ID from compute engine.
+ *
+ * Returns null if called outside GCE.
+ *
+ * @param callable $httpHandler Callback which delivers psr7 request
+ * @return string|null
+ */
+ public function getProjectId(?callable $httpHandler = null)
+ {
+ if ($this->projectId) {
+ return $this->projectId;
+ }
+ $httpHandler = $httpHandler ?: HttpHandlerFactory::build(HttpClientCache::getHttpClient());
+ if (!$this->hasCheckedOnGce) {
+ $this->isOnGce = self::onGce($httpHandler);
+ $this->hasCheckedOnGce = \true;
+ }
+ if (!$this->isOnGce) {
+ return null;
+ }
+ $this->projectId = $this->getFromMetadata($httpHandler, self::getProjectIdUri());
+ return $this->projectId;
+ }
+ /**
+ * Fetch the default universe domain from the metadata server.
+ *
+ * @param callable $httpHandler Callback which delivers psr7 request
+ * @return string
+ */
+ public function getUniverseDomain(?callable $httpHandler = null) : string
+ {
+ if (null !== $this->universeDomain) {
+ return $this->universeDomain;
+ }
+ $httpHandler = $httpHandler ?: HttpHandlerFactory::build(HttpClientCache::getHttpClient());
+ if (!$this->hasCheckedOnGce) {
+ $this->isOnGce = self::onGce($httpHandler);
+ $this->hasCheckedOnGce = \true;
+ }
+ try {
+ $this->universeDomain = $this->getFromMetadata($httpHandler, self::getUniverseDomainUri());
+ } catch (ClientException $e) {
+ // If the metadata server exists, but returns a 404 for the universe domain, the auth
+ // libraries should safely assume this is an older metadata server running in GCU, and
+ // should return the default universe domain.
+ if (!$e->hasResponse() || 404 != $e->getResponse()->getStatusCode()) {
+ throw $e;
+ }
+ $this->universeDomain = self::DEFAULT_UNIVERSE_DOMAIN;
+ }
+ // We expect in some cases the metadata server will return an empty string for the universe
+ // domain. In this case, the auth library MUST return the default universe domain.
+ if ('' === $this->universeDomain) {
+ $this->universeDomain = self::DEFAULT_UNIVERSE_DOMAIN;
+ }
+ return $this->universeDomain;
+ }
+ /**
+ * Fetch the value of a GCE metadata server URI.
+ *
+ * @param callable $httpHandler An HTTP Handler to deliver PSR7 requests.
+ * @param string $uri The metadata URI.
+ * @return string
+ */
+ private function getFromMetadata(callable $httpHandler, $uri)
+ {
+ $resp = $httpHandler(new Request('GET', $uri, [self::FLAVOR_HEADER => 'Google']));
+ return (string) $resp->getBody();
+ }
+ /**
+ * Get the quota project used for this API request
+ *
+ * @return string|null
+ */
+ public function getQuotaProject()
+ {
+ return $this->quotaProject;
+ }
+ /**
+ * Set whether or not we've already checked the GCE environment.
+ *
+ * @param bool $isOnGce
+ *
+ * @return void
+ */
+ public function setIsOnGce($isOnGce)
+ {
+ // Implicitly set hasCheckedGce to true
+ $this->hasCheckedOnGce = \true;
+ // Set isOnGce
+ $this->isOnGce = $isOnGce;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Credentials/IAMCredentials.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Credentials/IAMCredentials.php
new file mode 100755
index 00000000..3ebe72df
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Credentials/IAMCredentials.php
@@ -0,0 +1,77 @@
+selector = $selector;
+ $this->token = $token;
+ }
+ /**
+ * export a callback function which updates runtime metadata.
+ *
+ * @return callable updateMetadata function
+ */
+ public function getUpdateMetadataFunc()
+ {
+ return [$this, 'updateMetadata'];
+ }
+ /**
+ * Updates metadata with the appropriate header metadata.
+ *
+ * @param array $metadata metadata hashmap
+ * @param string $unusedAuthUri optional auth uri
+ * @param callable $httpHandler callback which delivers psr7 request
+ * Note: this param is unused here, only included here for
+ * consistency with other credentials class
+ *
+ * @return array updated metadata hashmap
+ */
+ public function updateMetadata($metadata, $unusedAuthUri = null, ?callable $httpHandler = null)
+ {
+ $metadata_copy = $metadata;
+ $metadata_copy[self::SELECTOR_KEY] = $this->selector;
+ $metadata_copy[self::TOKEN_KEY] = $this->token;
+ return $metadata_copy;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Credentials/ImpersonatedServiceAccountCredentials.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Credentials/ImpersonatedServiceAccountCredentials.php
new file mode 100755
index 00000000..a85a3f06
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Credentials/ImpersonatedServiceAccountCredentials.php
@@ -0,0 +1,120 @@
+ $jsonKey JSON credential file path or JSON credentials
+ * as an associative array.
+ */
+ public function __construct($scope, $jsonKey)
+ {
+ if (\is_string($jsonKey)) {
+ if (!\file_exists($jsonKey)) {
+ throw new \InvalidArgumentException('file does not exist');
+ }
+ $json = \file_get_contents($jsonKey);
+ if (!($jsonKey = \json_decode((string) $json, \true))) {
+ throw new \LogicException('invalid json for auth config');
+ }
+ }
+ if (!\array_key_exists('service_account_impersonation_url', $jsonKey)) {
+ throw new \LogicException('json key is missing the service_account_impersonation_url field');
+ }
+ if (!\array_key_exists('source_credentials', $jsonKey)) {
+ throw new \LogicException('json key is missing the source_credentials field');
+ }
+ $this->impersonatedServiceAccountName = $this->getImpersonatedServiceAccountNameFromUrl($jsonKey['service_account_impersonation_url']);
+ $this->sourceCredentials = new UserRefreshCredentials($scope, $jsonKey['source_credentials']);
+ }
+ /**
+ * Helper function for extracting the Server Account Name from the URL saved in the account
+ * credentials file.
+ *
+ * @param $serviceAccountImpersonationUrl string URL from "service_account_impersonation_url"
+ * @return string Service account email or ID.
+ */
+ private function getImpersonatedServiceAccountNameFromUrl(string $serviceAccountImpersonationUrl) : string
+ {
+ $fields = \explode('/', $serviceAccountImpersonationUrl);
+ $lastField = \end($fields);
+ $splitter = \explode(':', $lastField);
+ return $splitter[0];
+ }
+ /**
+ * Get the client name from the keyfile
+ *
+ * In this implementation, it will return the issuers email from the oauth token.
+ *
+ * @param callable|null $unusedHttpHandler not used by this credentials type.
+ * @return string Token issuer email
+ */
+ public function getClientName(?callable $unusedHttpHandler = null)
+ {
+ return $this->impersonatedServiceAccountName;
+ }
+ /**
+ * @param callable $httpHandler
+ *
+ * @return array {
+ * A set of auth related metadata, containing the following
+ *
+ * @type string $access_token
+ * @type int $expires_in
+ * @type string $scope
+ * @type string $token_type
+ * @type string $id_token
+ * }
+ */
+ public function fetchAuthToken(?callable $httpHandler = null)
+ {
+ return $this->sourceCredentials->fetchAuthToken($httpHandler);
+ }
+ /**
+ * @return string
+ */
+ public function getCacheKey()
+ {
+ return $this->sourceCredentials->getCacheKey();
+ }
+ /**
+ * @return array
+ */
+ public function getLastReceivedToken()
+ {
+ return $this->sourceCredentials->getLastReceivedToken();
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Credentials/InsecureCredentials.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Credentials/InsecureCredentials.php
new file mode 100755
index 00000000..a2b3090a
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Credentials/InsecureCredentials.php
@@ -0,0 +1,62 @@
+ ''];
+ /**
+ * Fetches the auth token. In this case it returns an empty string.
+ *
+ * @param callable $httpHandler
+ * @return array{access_token:string} A set of auth related metadata
+ */
+ public function fetchAuthToken(?callable $httpHandler = null)
+ {
+ return $this->token;
+ }
+ /**
+ * Returns the cache key. In this case it returns a null value, disabling
+ * caching.
+ *
+ * @return string|null
+ */
+ public function getCacheKey()
+ {
+ return null;
+ }
+ /**
+ * Fetches the last received token. In this case, it returns the same empty string
+ * auth token.
+ *
+ * @return array{access_token:string}
+ */
+ public function getLastReceivedToken()
+ {
+ return $this->token;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Credentials/ServiceAccountCredentials.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Credentials/ServiceAccountCredentials.php
new file mode 100755
index 00000000..ef871174
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Credentials/ServiceAccountCredentials.php
@@ -0,0 +1,312 @@
+push($middleware);
+ *
+ * $client = new Client([
+ * 'handler' => $stack,
+ * 'base_uri' => 'https://www.googleapis.com/taskqueue/v1beta2/projects/',
+ * 'auth' => 'google_auth' // authorize all requests
+ * ]);
+ *
+ * $res = $client->get('myproject/taskqueues/myqueue');
+ */
+class ServiceAccountCredentials extends CredentialsLoader implements GetQuotaProjectInterface, SignBlobInterface, ProjectIdProviderInterface
+{
+ use ServiceAccountSignerTrait;
+ /**
+ * The OAuth2 instance used to conduct authorization.
+ *
+ * @var OAuth2
+ */
+ protected $auth;
+ /**
+ * The quota project associated with the JSON credentials
+ *
+ * @var string
+ */
+ protected $quotaProject;
+ /**
+ * @var string|null
+ */
+ protected $projectId;
+ /**
+ * @var array|null
+ */
+ private $lastReceivedJwtAccessToken;
+ /**
+ * @var bool
+ */
+ private $useJwtAccessWithScope = \false;
+ /**
+ * @var ServiceAccountJwtAccessCredentials|null
+ */
+ private $jwtAccessCredentials;
+ /**
+ * @var string
+ */
+ private string $universeDomain;
+ /**
+ * Create a new ServiceAccountCredentials.
+ *
+ * @param string|string[]|null $scope the scope of the access request, expressed
+ * either as an Array or as a space-delimited String.
+ * @param string|array $jsonKey JSON credential file path or JSON credentials
+ * as an associative array
+ * @param string $sub an email address account to impersonate, in situations when
+ * the service account has been delegated domain wide access.
+ * @param string $targetAudience The audience for the ID token.
+ */
+ public function __construct($scope, $jsonKey, $sub = null, $targetAudience = null)
+ {
+ if (\is_string($jsonKey)) {
+ if (!\file_exists($jsonKey)) {
+ throw new \InvalidArgumentException('file does not exist');
+ }
+ $jsonKeyStream = \file_get_contents($jsonKey);
+ if (!($jsonKey = \json_decode((string) $jsonKeyStream, \true))) {
+ throw new \LogicException('invalid json for auth config');
+ }
+ }
+ if (!\array_key_exists('client_email', $jsonKey)) {
+ throw new \InvalidArgumentException('json key is missing the client_email field');
+ }
+ if (!\array_key_exists('private_key', $jsonKey)) {
+ throw new \InvalidArgumentException('json key is missing the private_key field');
+ }
+ if (\array_key_exists('quota_project_id', $jsonKey)) {
+ $this->quotaProject = (string) $jsonKey['quota_project_id'];
+ }
+ if ($scope && $targetAudience) {
+ throw new InvalidArgumentException('Scope and targetAudience cannot both be supplied');
+ }
+ $additionalClaims = [];
+ if ($targetAudience) {
+ $additionalClaims = ['target_audience' => $targetAudience];
+ }
+ $this->auth = new OAuth2(['audience' => self::TOKEN_CREDENTIAL_URI, 'issuer' => $jsonKey['client_email'], 'scope' => $scope, 'signingAlgorithm' => 'RS256', 'signingKey' => $jsonKey['private_key'], 'sub' => $sub, 'tokenCredentialUri' => self::TOKEN_CREDENTIAL_URI, 'additionalClaims' => $additionalClaims]);
+ $this->projectId = $jsonKey['project_id'] ?? null;
+ $this->universeDomain = $jsonKey['universe_domain'] ?? self::DEFAULT_UNIVERSE_DOMAIN;
+ }
+ /**
+ * When called, the ServiceAccountCredentials will use an instance of
+ * ServiceAccountJwtAccessCredentials to fetch (self-sign) an access token
+ * even when only scopes are supplied. Otherwise,
+ * ServiceAccountJwtAccessCredentials is only called when no scopes and an
+ * authUrl (audience) is suppled.
+ *
+ * @return void
+ */
+ public function useJwtAccessWithScope()
+ {
+ $this->useJwtAccessWithScope = \true;
+ }
+ /**
+ * @param callable $httpHandler
+ *
+ * @return array {
+ * A set of auth related metadata, containing the following
+ *
+ * @type string $access_token
+ * @type int $expires_in
+ * @type string $token_type
+ * }
+ */
+ public function fetchAuthToken(?callable $httpHandler = null)
+ {
+ if ($this->useSelfSignedJwt()) {
+ $jwtCreds = $this->createJwtAccessCredentials();
+ $accessToken = $jwtCreds->fetchAuthToken($httpHandler);
+ if ($lastReceivedToken = $jwtCreds->getLastReceivedToken()) {
+ // Keep self-signed JWTs in memory as the last received token
+ $this->lastReceivedJwtAccessToken = $lastReceivedToken;
+ }
+ return $accessToken;
+ }
+ return $this->auth->fetchAuthToken($httpHandler);
+ }
+ /**
+ * @return string
+ */
+ public function getCacheKey()
+ {
+ $key = $this->auth->getIssuer() . ':' . $this->auth->getCacheKey();
+ if ($sub = $this->auth->getSub()) {
+ $key .= ':' . $sub;
+ }
+ return $key;
+ }
+ /**
+ * @return array
+ */
+ public function getLastReceivedToken()
+ {
+ // If self-signed JWTs are being used, fetch the last received token
+ // from memory. Else, fetch it from OAuth2
+ return $this->useSelfSignedJwt() ? $this->lastReceivedJwtAccessToken : $this->auth->getLastReceivedToken();
+ }
+ /**
+ * Get the project ID from the service account keyfile.
+ *
+ * Returns null if the project ID does not exist in the keyfile.
+ *
+ * @param callable $httpHandler Not used by this credentials type.
+ * @return string|null
+ */
+ public function getProjectId(?callable $httpHandler = null)
+ {
+ return $this->projectId;
+ }
+ /**
+ * Updates metadata with the authorization token.
+ *
+ * @param array $metadata metadata hashmap
+ * @param string $authUri optional auth uri
+ * @param callable $httpHandler callback which delivers psr7 request
+ * @return array updated metadata hashmap
+ */
+ public function updateMetadata($metadata, $authUri = null, ?callable $httpHandler = null)
+ {
+ // scope exists. use oauth implementation
+ if (!$this->useSelfSignedJwt()) {
+ return parent::updateMetadata($metadata, $authUri, $httpHandler);
+ }
+ $jwtCreds = $this->createJwtAccessCredentials();
+ if ($this->auth->getScope()) {
+ // Prefer user-provided "scope" to "audience"
+ $updatedMetadata = $jwtCreds->updateMetadata($metadata, null, $httpHandler);
+ } else {
+ $updatedMetadata = $jwtCreds->updateMetadata($metadata, $authUri, $httpHandler);
+ }
+ if ($lastReceivedToken = $jwtCreds->getLastReceivedToken()) {
+ // Keep self-signed JWTs in memory as the last received token
+ $this->lastReceivedJwtAccessToken = $lastReceivedToken;
+ }
+ return $updatedMetadata;
+ }
+ /**
+ * @return ServiceAccountJwtAccessCredentials
+ */
+ private function createJwtAccessCredentials()
+ {
+ if (!$this->jwtAccessCredentials) {
+ // Create credentials for self-signing a JWT (JwtAccess)
+ $credJson = ['private_key' => $this->auth->getSigningKey(), 'client_email' => $this->auth->getIssuer()];
+ $this->jwtAccessCredentials = new ServiceAccountJwtAccessCredentials($credJson, $this->auth->getScope());
+ }
+ return $this->jwtAccessCredentials;
+ }
+ /**
+ * @param string $sub an email address account to impersonate, in situations when
+ * the service account has been delegated domain wide access.
+ * @return void
+ */
+ public function setSub($sub)
+ {
+ $this->auth->setSub($sub);
+ }
+ /**
+ * Get the client name from the keyfile.
+ *
+ * In this case, it returns the keyfile's client_email key.
+ *
+ * @param callable $httpHandler Not used by this credentials type.
+ * @return string
+ */
+ public function getClientName(?callable $httpHandler = null)
+ {
+ return $this->auth->getIssuer();
+ }
+ /**
+ * Get the quota project used for this API request
+ *
+ * @return string|null
+ */
+ public function getQuotaProject()
+ {
+ return $this->quotaProject;
+ }
+ /**
+ * Get the universe domain configured in the JSON credential.
+ *
+ * @return string
+ */
+ public function getUniverseDomain() : string
+ {
+ return $this->universeDomain;
+ }
+ /**
+ * @return bool
+ */
+ private function useSelfSignedJwt()
+ {
+ // When a sub is supplied, the user is using domain-wide delegation, which not available
+ // with self-signed JWTs
+ if (null !== $this->auth->getSub()) {
+ // If we are outside the GDU, we can't use domain-wide delegation
+ if ($this->getUniverseDomain() !== self::DEFAULT_UNIVERSE_DOMAIN) {
+ throw new \LogicException(\sprintf('Service Account subject is configured for the credential. Domain-wide ' . 'delegation is not supported in universes other than %s.', self::DEFAULT_UNIVERSE_DOMAIN));
+ }
+ return \false;
+ }
+ // If claims are set, this call is for "id_tokens"
+ if ($this->auth->getAdditionalClaims()) {
+ return \false;
+ }
+ // When true, ServiceAccountCredentials will always use JwtAccess for access tokens
+ if ($this->useJwtAccessWithScope) {
+ return \true;
+ }
+ // If the universe domain is outside the GDU, use JwtAccess for access tokens
+ if ($this->getUniverseDomain() !== self::DEFAULT_UNIVERSE_DOMAIN) {
+ return \true;
+ }
+ return \is_null($this->auth->getScope());
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Credentials/ServiceAccountJwtAccessCredentials.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Credentials/ServiceAccountJwtAccessCredentials.php
new file mode 100755
index 00000000..d9dff7fa
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Credentials/ServiceAccountJwtAccessCredentials.php
@@ -0,0 +1,171 @@
+ $jsonKey JSON credential file path or JSON credentials
+ * as an associative array
+ * @param string|string[] $scope the scope of the access request, expressed
+ * either as an Array or as a space-delimited String.
+ */
+ public function __construct($jsonKey, $scope = null)
+ {
+ if (\is_string($jsonKey)) {
+ if (!\file_exists($jsonKey)) {
+ throw new \InvalidArgumentException('file does not exist');
+ }
+ $jsonKeyStream = \file_get_contents($jsonKey);
+ if (!($jsonKey = \json_decode((string) $jsonKeyStream, \true))) {
+ throw new \LogicException('invalid json for auth config');
+ }
+ }
+ if (!\array_key_exists('client_email', $jsonKey)) {
+ throw new \InvalidArgumentException('json key is missing the client_email field');
+ }
+ if (!\array_key_exists('private_key', $jsonKey)) {
+ throw new \InvalidArgumentException('json key is missing the private_key field');
+ }
+ if (\array_key_exists('quota_project_id', $jsonKey)) {
+ $this->quotaProject = (string) $jsonKey['quota_project_id'];
+ }
+ $this->auth = new OAuth2(['issuer' => $jsonKey['client_email'], 'sub' => $jsonKey['client_email'], 'signingAlgorithm' => 'RS256', 'signingKey' => $jsonKey['private_key'], 'scope' => $scope]);
+ $this->projectId = $jsonKey['project_id'] ?? null;
+ }
+ /**
+ * Updates metadata with the authorization token.
+ *
+ * @param array $metadata metadata hashmap
+ * @param string $authUri optional auth uri
+ * @param callable $httpHandler callback which delivers psr7 request
+ * @return array updated metadata hashmap
+ */
+ public function updateMetadata($metadata, $authUri = null, ?callable $httpHandler = null)
+ {
+ $scope = $this->auth->getScope();
+ if (empty($authUri) && empty($scope)) {
+ return $metadata;
+ }
+ $this->auth->setAudience($authUri);
+ return parent::updateMetadata($metadata, $authUri, $httpHandler);
+ }
+ /**
+ * Implements FetchAuthTokenInterface#fetchAuthToken.
+ *
+ * @param callable $httpHandler
+ *
+ * @return null|array{access_token:string} A set of auth related metadata
+ */
+ public function fetchAuthToken(?callable $httpHandler = null)
+ {
+ $audience = $this->auth->getAudience();
+ $scope = $this->auth->getScope();
+ if (empty($audience) && empty($scope)) {
+ return null;
+ }
+ if (!empty($audience) && !empty($scope)) {
+ throw new \UnexpectedValueException('Cannot sign both audience and scope in JwtAccess');
+ }
+ $access_token = $this->auth->toJwt();
+ // Set the self-signed access token in OAuth2 for getLastReceivedToken
+ $this->auth->setAccessToken($access_token);
+ return ['access_token' => $access_token, 'expires_in' => $this->auth->getExpiry(), 'token_type' => 'Bearer'];
+ }
+ /**
+ * @return string
+ */
+ public function getCacheKey()
+ {
+ return $this->auth->getCacheKey();
+ }
+ /**
+ * @return array
+ */
+ public function getLastReceivedToken()
+ {
+ return $this->auth->getLastReceivedToken();
+ }
+ /**
+ * Get the project ID from the service account keyfile.
+ *
+ * Returns null if the project ID does not exist in the keyfile.
+ *
+ * @param callable $httpHandler Not used by this credentials type.
+ * @return string|null
+ */
+ public function getProjectId(?callable $httpHandler = null)
+ {
+ return $this->projectId;
+ }
+ /**
+ * Get the client name from the keyfile.
+ *
+ * In this case, it returns the keyfile's client_email key.
+ *
+ * @param callable $httpHandler Not used by this credentials type.
+ * @return string
+ */
+ public function getClientName(?callable $httpHandler = null)
+ {
+ return $this->auth->getIssuer();
+ }
+ /**
+ * Get the quota project used for this API request
+ *
+ * @return string|null
+ */
+ public function getQuotaProject()
+ {
+ return $this->quotaProject;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Credentials/UserRefreshCredentials.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Credentials/UserRefreshCredentials.php
new file mode 100755
index 00000000..482c65cc
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Credentials/UserRefreshCredentials.php
@@ -0,0 +1,130 @@
+ $jsonKey JSON credential file path or JSON credentials
+ * as an associative array
+ */
+ public function __construct($scope, $jsonKey)
+ {
+ if (\is_string($jsonKey)) {
+ if (!\file_exists($jsonKey)) {
+ throw new \InvalidArgumentException('file does not exist');
+ }
+ $json = \file_get_contents($jsonKey);
+ if (!($jsonKey = \json_decode((string) $json, \true))) {
+ throw new \LogicException('invalid json for auth config');
+ }
+ }
+ if (!\array_key_exists('client_id', $jsonKey)) {
+ throw new \InvalidArgumentException('json key is missing the client_id field');
+ }
+ if (!\array_key_exists('client_secret', $jsonKey)) {
+ throw new \InvalidArgumentException('json key is missing the client_secret field');
+ }
+ if (!\array_key_exists('refresh_token', $jsonKey)) {
+ throw new \InvalidArgumentException('json key is missing the refresh_token field');
+ }
+ $this->auth = new OAuth2(['clientId' => $jsonKey['client_id'], 'clientSecret' => $jsonKey['client_secret'], 'refresh_token' => $jsonKey['refresh_token'], 'scope' => $scope, 'tokenCredentialUri' => self::TOKEN_CREDENTIAL_URI]);
+ if (\array_key_exists('quota_project_id', $jsonKey)) {
+ $this->quotaProject = (string) $jsonKey['quota_project_id'];
+ }
+ }
+ /**
+ * @param callable $httpHandler
+ *
+ * @return array {
+ * A set of auth related metadata, containing the following
+ *
+ * @type string $access_token
+ * @type int $expires_in
+ * @type string $scope
+ * @type string $token_type
+ * @type string $id_token
+ * }
+ */
+ public function fetchAuthToken(?callable $httpHandler = null)
+ {
+ return $this->auth->fetchAuthToken($httpHandler);
+ }
+ /**
+ * @return string
+ */
+ public function getCacheKey()
+ {
+ return $this->auth->getClientId() . ':' . $this->auth->getCacheKey();
+ }
+ /**
+ * @return array
+ */
+ public function getLastReceivedToken()
+ {
+ return $this->auth->getLastReceivedToken();
+ }
+ /**
+ * Get the quota project used for this API request
+ *
+ * @return string|null
+ */
+ public function getQuotaProject()
+ {
+ return $this->quotaProject;
+ }
+ /**
+ * Get the granted scopes (if they exist) for the last fetched token.
+ *
+ * @return string|null
+ */
+ public function getGrantedScope()
+ {
+ return $this->auth->getGrantedScope();
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/CredentialsLoader.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/CredentialsLoader.php
new file mode 100755
index 00000000..0d4fea47
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/CredentialsLoader.php
@@ -0,0 +1,242 @@
+|null JSON key | null
+ */
+ public static function fromEnv()
+ {
+ $path = \getenv(self::ENV_VAR);
+ if (empty($path)) {
+ return null;
+ }
+ if (!\file_exists($path)) {
+ $cause = 'file ' . $path . ' does not exist';
+ throw new \DomainException(self::unableToReadEnv($cause));
+ }
+ $jsonKey = \file_get_contents($path);
+ return \json_decode((string) $jsonKey, \true);
+ }
+ /**
+ * Load a JSON key from a well known path.
+ *
+ * The well known path is OS dependent:
+ *
+ * * windows: %APPDATA%/gcloud/application_default_credentials.json
+ * * others: $HOME/.config/gcloud/application_default_credentials.json
+ *
+ * If the file does not exist, this returns null.
+ *
+ * @return array|null JSON key | null
+ */
+ public static function fromWellKnownFile()
+ {
+ $rootEnv = self::isOnWindows() ? 'APPDATA' : 'HOME';
+ $path = [\getenv($rootEnv)];
+ if (!self::isOnWindows()) {
+ $path[] = self::NON_WINDOWS_WELL_KNOWN_PATH_BASE;
+ }
+ $path[] = self::WELL_KNOWN_PATH;
+ $path = \implode(\DIRECTORY_SEPARATOR, $path);
+ if (!\file_exists($path)) {
+ return null;
+ }
+ $jsonKey = \file_get_contents($path);
+ return \json_decode((string) $jsonKey, \true);
+ }
+ /**
+ * Create a new Credentials instance.
+ *
+ * @param string|string[] $scope the scope of the access request, expressed
+ * either as an Array or as a space-delimited String.
+ * @param array $jsonKey the JSON credentials.
+ * @param string|string[] $defaultScope The default scope to use if no
+ * user-defined scopes exist, expressed either as an Array or as a
+ * space-delimited string.
+ *
+ * @return ServiceAccountCredentials|UserRefreshCredentials|ImpersonatedServiceAccountCredentials|ExternalAccountCredentials
+ */
+ public static function makeCredentials($scope, array $jsonKey, $defaultScope = null)
+ {
+ if (!\array_key_exists('type', $jsonKey)) {
+ throw new \InvalidArgumentException('json key is missing the type field');
+ }
+ if ($jsonKey['type'] == 'service_account') {
+ // Do not pass $defaultScope to ServiceAccountCredentials
+ return new ServiceAccountCredentials($scope, $jsonKey);
+ }
+ if ($jsonKey['type'] == 'authorized_user') {
+ $anyScope = $scope ?: $defaultScope;
+ return new UserRefreshCredentials($anyScope, $jsonKey);
+ }
+ if ($jsonKey['type'] == 'impersonated_service_account') {
+ $anyScope = $scope ?: $defaultScope;
+ return new ImpersonatedServiceAccountCredentials($anyScope, $jsonKey);
+ }
+ if ($jsonKey['type'] == 'external_account') {
+ $anyScope = $scope ?: $defaultScope;
+ return new ExternalAccountCredentials($anyScope, $jsonKey);
+ }
+ throw new \InvalidArgumentException('invalid value in the type field');
+ }
+ /**
+ * Create an authorized HTTP Client from an instance of FetchAuthTokenInterface.
+ *
+ * @param FetchAuthTokenInterface $fetcher is used to fetch the auth token
+ * @param array $httpClientOptions (optional) Array of request options to apply.
+ * @param callable $httpHandler (optional) http client to fetch the token.
+ * @param callable $tokenCallback (optional) function to be called when a new token is fetched.
+ * @return \GuzzleHttp\Client
+ */
+ public static function makeHttpClient(FetchAuthTokenInterface $fetcher, array $httpClientOptions = [], ?callable $httpHandler = null, ?callable $tokenCallback = null)
+ {
+ $middleware = new Middleware\AuthTokenMiddleware($fetcher, $httpHandler, $tokenCallback);
+ $stack = \WPMailSMTP\Vendor\GuzzleHttp\HandlerStack::create();
+ $stack->push($middleware);
+ return new \WPMailSMTP\Vendor\GuzzleHttp\Client(['handler' => $stack, 'auth' => 'google_auth'] + $httpClientOptions);
+ }
+ /**
+ * Create a new instance of InsecureCredentials.
+ *
+ * @return InsecureCredentials
+ */
+ public static function makeInsecureCredentials()
+ {
+ return new InsecureCredentials();
+ }
+ /**
+ * Fetch a quota project from the environment variable
+ * GOOGLE_CLOUD_QUOTA_PROJECT. Return null if
+ * GOOGLE_CLOUD_QUOTA_PROJECT is not specified.
+ *
+ * @return string|null
+ */
+ public static function quotaProjectFromEnv()
+ {
+ return \getenv(self::QUOTA_PROJECT_ENV_VAR) ?: null;
+ }
+ /**
+ * Gets a callable which returns the default device certification.
+ *
+ * @throws UnexpectedValueException
+ * @return callable|null
+ */
+ public static function getDefaultClientCertSource()
+ {
+ if (!($clientCertSourceJson = self::loadDefaultClientCertSourceFile())) {
+ return null;
+ }
+ $clientCertSourceCmd = $clientCertSourceJson['cert_provider_command'];
+ return function () use($clientCertSourceCmd) {
+ $cmd = \array_map('escapeshellarg', $clientCertSourceCmd);
+ \exec(\implode(' ', $cmd), $output, $returnVar);
+ if (0 === $returnVar) {
+ return \implode(\PHP_EOL, $output);
+ }
+ throw new RuntimeException('"cert_provider_command" failed with a nonzero exit code');
+ };
+ }
+ /**
+ * Determines whether or not the default device certificate should be loaded.
+ *
+ * @return bool
+ */
+ public static function shouldLoadClientCertSource()
+ {
+ return \filter_var(\getenv(self::MTLS_CERT_ENV_VAR), \FILTER_VALIDATE_BOOLEAN);
+ }
+ /**
+ * @return array{cert_provider_command:string[]}|null
+ */
+ private static function loadDefaultClientCertSourceFile()
+ {
+ $rootEnv = self::isOnWindows() ? 'APPDATA' : 'HOME';
+ $path = \sprintf('%s/%s', \getenv($rootEnv), self::MTLS_WELL_KNOWN_PATH);
+ if (!\file_exists($path)) {
+ return null;
+ }
+ $jsonKey = \file_get_contents($path);
+ $clientCertSourceJson = \json_decode((string) $jsonKey, \true);
+ if (!$clientCertSourceJson) {
+ throw new UnexpectedValueException('Invalid client cert source JSON');
+ }
+ if (!isset($clientCertSourceJson['cert_provider_command'])) {
+ throw new UnexpectedValueException('cert source requires "cert_provider_command"');
+ }
+ if (!\is_array($clientCertSourceJson['cert_provider_command'])) {
+ throw new UnexpectedValueException('cert source expects "cert_provider_command" to be an array');
+ }
+ return $clientCertSourceJson;
+ }
+ /**
+ * Get the universe domain from the credential. Defaults to "googleapis.com"
+ * for all credential types which do not support universe domain.
+ *
+ * @return string
+ */
+ public function getUniverseDomain() : string
+ {
+ return self::DEFAULT_UNIVERSE_DOMAIN;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/ExternalAccountCredentialSourceInterface.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/ExternalAccountCredentialSourceInterface.php
new file mode 100755
index 00000000..d47171c3
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/ExternalAccountCredentialSourceInterface.php
@@ -0,0 +1,23 @@
+ $cacheConfig Configuration for the cache
+ * @param CacheItemPoolInterface $cache
+ */
+ public function __construct(FetchAuthTokenInterface $fetcher, ?array $cacheConfig = null, ?CacheItemPoolInterface $cache = null)
+ {
+ $this->fetcher = $fetcher;
+ $this->cache = $cache;
+ $this->cacheConfig = \array_merge(['lifetime' => 1500, 'prefix' => '', 'cacheUniverseDomain' => $fetcher instanceof Credentials\GCECredentials], (array) $cacheConfig);
+ }
+ /**
+ * @return FetchAuthTokenInterface
+ */
+ public function getFetcher()
+ {
+ return $this->fetcher;
+ }
+ /**
+ * Implements FetchAuthTokenInterface#fetchAuthToken.
+ *
+ * Checks the cache for a valid auth token and fetches the auth tokens
+ * from the supplied fetcher.
+ *
+ * @param callable $httpHandler callback which delivers psr7 request
+ * @return array the response
+ * @throws \Exception
+ */
+ public function fetchAuthToken(?callable $httpHandler = null)
+ {
+ if ($cached = $this->fetchAuthTokenFromCache()) {
+ return $cached;
+ }
+ $auth_token = $this->fetcher->fetchAuthToken($httpHandler);
+ $this->saveAuthTokenInCache($auth_token);
+ return $auth_token;
+ }
+ /**
+ * @return string
+ */
+ public function getCacheKey()
+ {
+ return $this->getFullCacheKey($this->fetcher->getCacheKey());
+ }
+ /**
+ * @return array|null
+ */
+ public function getLastReceivedToken()
+ {
+ return $this->fetcher->getLastReceivedToken();
+ }
+ /**
+ * Get the client name from the fetcher.
+ *
+ * @param callable $httpHandler An HTTP handler to deliver PSR7 requests.
+ * @return string
+ */
+ public function getClientName(?callable $httpHandler = null)
+ {
+ if (!$this->fetcher instanceof SignBlobInterface) {
+ throw new \RuntimeException('Credentials fetcher does not implement ' . 'Google\\Auth\\SignBlobInterface');
+ }
+ return $this->fetcher->getClientName($httpHandler);
+ }
+ /**
+ * Sign a blob using the fetcher.
+ *
+ * @param string $stringToSign The string to sign.
+ * @param bool $forceOpenSsl Require use of OpenSSL for local signing. Does
+ * not apply to signing done using external services. **Defaults to**
+ * `false`.
+ * @return string The resulting signature.
+ * @throws \RuntimeException If the fetcher does not implement
+ * `Google\Auth\SignBlobInterface`.
+ */
+ public function signBlob($stringToSign, $forceOpenSsl = \false)
+ {
+ if (!$this->fetcher instanceof SignBlobInterface) {
+ throw new \RuntimeException('Credentials fetcher does not implement ' . 'Google\\Auth\\SignBlobInterface');
+ }
+ // Pass the access token from cache for credentials that sign blobs
+ // using the IAM API. This saves a call to fetch an access token when a
+ // cached token exists.
+ if ($this->fetcher instanceof Credentials\GCECredentials || $this->fetcher instanceof Credentials\ImpersonatedServiceAccountCredentials) {
+ $cached = $this->fetchAuthTokenFromCache();
+ $accessToken = $cached['access_token'] ?? null;
+ return $this->fetcher->signBlob($stringToSign, $forceOpenSsl, $accessToken);
+ }
+ return $this->fetcher->signBlob($stringToSign, $forceOpenSsl);
+ }
+ /**
+ * Get the quota project used for this API request from the credentials
+ * fetcher.
+ *
+ * @return string|null
+ */
+ public function getQuotaProject()
+ {
+ if ($this->fetcher instanceof GetQuotaProjectInterface) {
+ return $this->fetcher->getQuotaProject();
+ }
+ return null;
+ }
+ /*
+ * Get the Project ID from the fetcher.
+ *
+ * @param callable $httpHandler Callback which delivers psr7 request
+ * @return string|null
+ * @throws \RuntimeException If the fetcher does not implement
+ * `Google\Auth\ProvidesProjectIdInterface`.
+ */
+ public function getProjectId(?callable $httpHandler = null)
+ {
+ if (!$this->fetcher instanceof ProjectIdProviderInterface) {
+ throw new \RuntimeException('Credentials fetcher does not implement ' . 'Google\\Auth\\ProvidesProjectIdInterface');
+ }
+ // Pass the access token from cache for credentials that require an
+ // access token to fetch the project ID. This saves a call to fetch an
+ // access token when a cached token exists.
+ if ($this->fetcher instanceof Credentials\ExternalAccountCredentials) {
+ $cached = $this->fetchAuthTokenFromCache();
+ $accessToken = $cached['access_token'] ?? null;
+ return $this->fetcher->getProjectId($httpHandler, $accessToken);
+ }
+ return $this->fetcher->getProjectId($httpHandler);
+ }
+ /*
+ * Get the Universe Domain from the fetcher.
+ *
+ * @return string
+ */
+ public function getUniverseDomain() : string
+ {
+ if ($this->fetcher instanceof GetUniverseDomainInterface) {
+ if ($this->cacheConfig['cacheUniverseDomain']) {
+ return $this->getCachedUniverseDomain($this->fetcher);
+ }
+ return $this->fetcher->getUniverseDomain();
+ }
+ return GetUniverseDomainInterface::DEFAULT_UNIVERSE_DOMAIN;
+ }
+ /**
+ * Updates metadata with the authorization token.
+ *
+ * @param array $metadata metadata hashmap
+ * @param string $authUri optional auth uri
+ * @param callable $httpHandler callback which delivers psr7 request
+ * @return array updated metadata hashmap
+ * @throws \RuntimeException If the fetcher does not implement
+ * `Google\Auth\UpdateMetadataInterface`.
+ */
+ public function updateMetadata($metadata, $authUri = null, ?callable $httpHandler = null)
+ {
+ if (!$this->fetcher instanceof UpdateMetadataInterface) {
+ throw new \RuntimeException('Credentials fetcher does not implement ' . 'Google\\Auth\\UpdateMetadataInterface');
+ }
+ $cached = $this->fetchAuthTokenFromCache($authUri);
+ if ($cached) {
+ // Set the access token in the `Authorization` metadata header so
+ // the downstream call to updateMetadata know they don't need to
+ // fetch another token.
+ if (isset($cached['access_token'])) {
+ $metadata[self::AUTH_METADATA_KEY] = ['Bearer ' . $cached['access_token']];
+ } elseif (isset($cached['id_token'])) {
+ $metadata[self::AUTH_METADATA_KEY] = ['Bearer ' . $cached['id_token']];
+ }
+ }
+ $newMetadata = $this->fetcher->updateMetadata($metadata, $authUri, $httpHandler);
+ if (!$cached && ($token = $this->fetcher->getLastReceivedToken())) {
+ $this->saveAuthTokenInCache($token, $authUri);
+ }
+ return $newMetadata;
+ }
+ /**
+ * @param string|null $authUri
+ * @return array|null
+ */
+ private function fetchAuthTokenFromCache($authUri = null)
+ {
+ // Use the cached value if its available.
+ //
+ // TODO: correct caching; update the call to setCachedValue to set the expiry
+ // to the value returned with the auth token.
+ //
+ // TODO: correct caching; enable the cache to be cleared.
+ // if $authUri is set, use it as the cache key
+ $cacheKey = $authUri ? $this->getFullCacheKey($authUri) : $this->fetcher->getCacheKey();
+ $cached = $this->getCachedValue($cacheKey);
+ if (\is_array($cached)) {
+ if (empty($cached['expires_at'])) {
+ // If there is no expiration data, assume token is not expired.
+ // (for JwtAccess and ID tokens)
+ return $cached;
+ }
+ if (\time() + $this->eagerRefreshThresholdSeconds < $cached['expires_at']) {
+ // access token is not expired
+ return $cached;
+ }
+ }
+ return null;
+ }
+ /**
+ * @param array $authToken
+ * @param string|null $authUri
+ * @return void
+ */
+ private function saveAuthTokenInCache($authToken, $authUri = null)
+ {
+ if (isset($authToken['access_token']) || isset($authToken['id_token'])) {
+ // if $authUri is set, use it as the cache key
+ $cacheKey = $authUri ? $this->getFullCacheKey($authUri) : $this->fetcher->getCacheKey();
+ $this->setCachedValue($cacheKey, $authToken);
+ }
+ }
+ private function getCachedUniverseDomain(GetUniverseDomainInterface $fetcher) : string
+ {
+ $cacheKey = $this->getFullCacheKey($fetcher->getCacheKey() . 'universe_domain');
+ // @phpstan-ignore-line
+ if ($universeDomain = $this->getCachedValue($cacheKey)) {
+ return $universeDomain;
+ }
+ $universeDomain = $fetcher->getUniverseDomain();
+ $this->setCachedValue($cacheKey, $universeDomain);
+ return $universeDomain;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/FetchAuthTokenInterface.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/FetchAuthTokenInterface.php
new file mode 100755
index 00000000..6b74dd50
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/FetchAuthTokenInterface.php
@@ -0,0 +1,52 @@
+ a hash of auth tokens
+ */
+ public function fetchAuthToken(?callable $httpHandler = null);
+ /**
+ * Obtains a key that can used to cache the results of #fetchAuthToken.
+ *
+ * If the value is empty, the auth token is not cached.
+ *
+ * @return string a key that may be used to cache the auth token.
+ */
+ public function getCacheKey();
+ /**
+ * Returns an associative array with the token and
+ * expiration time.
+ *
+ * @return null|array {
+ * The last received access token.
+ *
+ * @type string $access_token The access token string.
+ * @type int $expires_at The time the token expires as a UNIX timestamp.
+ * }
+ */
+ public function getLastReceivedToken();
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/GCECache.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/GCECache.php
new file mode 100755
index 00000000..006c3b7d
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/GCECache.php
@@ -0,0 +1,70 @@
+ $cacheConfig Configuration for the cache
+ * @param CacheItemPoolInterface $cache
+ */
+ public function __construct(?array $cacheConfig = null, ?CacheItemPoolInterface $cache = null)
+ {
+ $this->cache = $cache;
+ $this->cacheConfig = \array_merge(['lifetime' => 1500, 'prefix' => ''], (array) $cacheConfig);
+ }
+ /**
+ * Caches the result of onGce so the metadata server is not called multiple
+ * times.
+ *
+ * @param callable $httpHandler callback which delivers psr7 request
+ * @return bool True if this a GCEInstance, false otherwise
+ */
+ public function onGce(?callable $httpHandler = null)
+ {
+ if (\is_null($this->cache)) {
+ return GCECredentials::onGce($httpHandler);
+ }
+ $cacheKey = self::GCE_CACHE_KEY;
+ $onGce = $this->getCachedValue($cacheKey);
+ if (\is_null($onGce)) {
+ $onGce = GCECredentials::onGce($httpHandler);
+ $this->setCachedValue($cacheKey, $onGce);
+ }
+ return $onGce;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/GetQuotaProjectInterface.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/GetQuotaProjectInterface.php
new file mode 100755
index 00000000..da6c3327
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/GetQuotaProjectInterface.php
@@ -0,0 +1,32 @@
+client = $client;
+ }
+ /**
+ * Accepts a PSR-7 request and an array of options and returns a PSR-7 response.
+ *
+ * @param RequestInterface $request
+ * @param array $options
+ * @return ResponseInterface
+ */
+ public function __invoke(RequestInterface $request, array $options = [])
+ {
+ return $this->client->send($request, $options);
+ }
+ /**
+ * Accepts a PSR-7 request and an array of options and returns a PromiseInterface
+ *
+ * @param RequestInterface $request
+ * @param array $options
+ *
+ * @return \GuzzleHttp\Promise\PromiseInterface
+ */
+ public function async(RequestInterface $request, array $options = [])
+ {
+ return $this->client->sendAsync($request, $options);
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/HttpHandler/Guzzle7HttpHandler.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/HttpHandler/Guzzle7HttpHandler.php
new file mode 100755
index 00000000..5a2b7ea9
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/HttpHandler/Guzzle7HttpHandler.php
@@ -0,0 +1,22 @@
+remove('http_errors');
+ $stack->unshift(Middleware::httpErrors($bodySummarizer), 'http_errors');
+ }
+ $client = new Client(['handler' => $stack]);
+ }
+ $version = null;
+ if (\defined('WPMailSMTP\\Vendor\\GuzzleHttp\\ClientInterface::MAJOR_VERSION')) {
+ $version = ClientInterface::MAJOR_VERSION;
+ } elseif (\defined('WPMailSMTP\\Vendor\\GuzzleHttp\\ClientInterface::VERSION')) {
+ $version = (int) \substr(ClientInterface::VERSION, 0, 1);
+ }
+ switch ($version) {
+ case 6:
+ return new Guzzle6HttpHandler($client);
+ case 7:
+ return new Guzzle7HttpHandler($client);
+ default:
+ throw new \Exception('Version not supported');
+ }
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Iam.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Iam.php
new file mode 100755
index 00000000..3816027a
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Iam.php
@@ -0,0 +1,86 @@
+httpHandler = $httpHandler ?: HttpHandlerFactory::build(HttpClientCache::getHttpClient());
+ $this->universeDomain = $universeDomain;
+ }
+ /**
+ * Sign a string using the IAM signBlob API.
+ *
+ * Note that signing using IAM requires your service account to have the
+ * `iam.serviceAccounts.signBlob` permission, part of the "Service Account
+ * Token Creator" IAM role.
+ *
+ * @param string $email The service account email.
+ * @param string $accessToken An access token from the service account.
+ * @param string $stringToSign The string to be signed.
+ * @param array $delegates [optional] A list of service account emails to
+ * add to the delegate chain. If omitted, the value of `$email` will
+ * be used.
+ * @return string The signed string, base64-encoded.
+ */
+ public function signBlob($email, $accessToken, $stringToSign, array $delegates = [])
+ {
+ $httpHandler = $this->httpHandler;
+ $name = \sprintf(self::SERVICE_ACCOUNT_NAME, $email);
+ $apiRoot = \str_replace('UNIVERSE_DOMAIN', $this->universeDomain, self::IAM_API_ROOT_TEMPLATE);
+ $uri = $apiRoot . '/' . \sprintf(self::SIGN_BLOB_PATH, $name);
+ if ($delegates) {
+ foreach ($delegates as &$delegate) {
+ $delegate = \sprintf(self::SERVICE_ACCOUNT_NAME, $delegate);
+ }
+ } else {
+ $delegates = [$name];
+ }
+ $body = ['delegates' => $delegates, 'payload' => \base64_encode($stringToSign)];
+ $headers = ['Authorization' => 'Bearer ' . $accessToken];
+ $request = new Psr7\Request('POST', $uri, $headers, Utils::streamFor(\json_encode($body)));
+ $res = $httpHandler($request);
+ $body = \json_decode((string) $res->getBody(), \true);
+ return $body['signedBlob'];
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/IamSignerTrait.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/IamSignerTrait.php
new file mode 100755
index 00000000..9b60029b
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/IamSignerTrait.php
@@ -0,0 +1,61 @@
+iam;
+ if (!$signer) {
+ $signer = $this instanceof GetUniverseDomainInterface ? new Iam($httpHandler, $this->getUniverseDomain()) : new Iam($httpHandler);
+ }
+ $email = $this->getClientName($httpHandler);
+ if (\is_null($accessToken)) {
+ $previousToken = $this->getLastReceivedToken();
+ $accessToken = $previousToken ? $previousToken['access_token'] : $this->fetchAuthToken($httpHandler)['access_token'];
+ }
+ return $signer->signBlob($email, $accessToken, $stringToSign);
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Middleware/AuthTokenMiddleware.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Middleware/AuthTokenMiddleware.php
new file mode 100755
index 00000000..d43cb116
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Middleware/AuthTokenMiddleware.php
@@ -0,0 +1,138 @@
+'
+ */
+class AuthTokenMiddleware
+{
+ /**
+ * @var callable
+ */
+ private $httpHandler;
+ /**
+ * It must be an implementation of FetchAuthTokenInterface.
+ * It may also implement UpdateMetadataInterface allowing direct
+ * retrieval of auth related headers
+ * @var FetchAuthTokenInterface
+ */
+ private $fetcher;
+ /**
+ * @var ?callable
+ */
+ private $tokenCallback;
+ /**
+ * Creates a new AuthTokenMiddleware.
+ *
+ * @param FetchAuthTokenInterface $fetcher is used to fetch the auth token
+ * @param callable $httpHandler (optional) callback which delivers psr7 request
+ * @param callable $tokenCallback (optional) function to be called when a new token is fetched.
+ */
+ public function __construct(FetchAuthTokenInterface $fetcher, ?callable $httpHandler = null, ?callable $tokenCallback = null)
+ {
+ $this->fetcher = $fetcher;
+ $this->httpHandler = $httpHandler;
+ $this->tokenCallback = $tokenCallback;
+ }
+ /**
+ * Updates the request with an Authorization header when auth is 'google_auth'.
+ *
+ * use Google\Auth\Middleware\AuthTokenMiddleware;
+ * use Google\Auth\OAuth2;
+ * use GuzzleHttp\Client;
+ * use GuzzleHttp\HandlerStack;
+ *
+ * $config = [...];
+ * $oauth2 = new OAuth2($config)
+ * $middleware = new AuthTokenMiddleware($oauth2);
+ * $stack = HandlerStack::create();
+ * $stack->push($middleware);
+ *
+ * $client = new Client([
+ * 'handler' => $stack,
+ * 'base_uri' => 'https://www.googleapis.com/taskqueue/v1beta2/projects/',
+ * 'auth' => 'google_auth' // authorize all requests
+ * ]);
+ *
+ * $res = $client->get('myproject/taskqueues/myqueue');
+ *
+ * @param callable $handler
+ * @return \Closure
+ */
+ public function __invoke(callable $handler)
+ {
+ return function (RequestInterface $request, array $options) use($handler) {
+ // Requests using "auth"="google_auth" will be authorized.
+ if (!isset($options['auth']) || $options['auth'] !== 'google_auth') {
+ return $handler($request, $options);
+ }
+ $request = $this->addAuthHeaders($request);
+ if ($quotaProject = $this->getQuotaProject()) {
+ $request = $request->withHeader(GetQuotaProjectInterface::X_GOOG_USER_PROJECT_HEADER, $quotaProject);
+ }
+ return $handler($request, $options);
+ };
+ }
+ /**
+ * Adds auth related headers to the request.
+ *
+ * @param RequestInterface $request
+ * @return RequestInterface
+ */
+ private function addAuthHeaders(RequestInterface $request)
+ {
+ if (!$this->fetcher instanceof UpdateMetadataInterface || $this->fetcher instanceof FetchAuthTokenCache && !$this->fetcher->getFetcher() instanceof UpdateMetadataInterface) {
+ $token = $this->fetcher->fetchAuthToken();
+ $request = $request->withHeader('authorization', 'Bearer ' . ($token['access_token'] ?? $token['id_token'] ?? ''));
+ } else {
+ $headers = $this->fetcher->updateMetadata($request->getHeaders(), null, $this->httpHandler);
+ $request = Utils::modifyRequest($request, ['set_headers' => $headers]);
+ }
+ if ($this->tokenCallback && ($token = $this->fetcher->getLastReceivedToken())) {
+ if (\array_key_exists('access_token', $token)) {
+ \call_user_func($this->tokenCallback, $this->fetcher->getCacheKey(), $token['access_token']);
+ }
+ }
+ return $request;
+ }
+ /**
+ * @return string|null
+ */
+ private function getQuotaProject()
+ {
+ if ($this->fetcher instanceof GetQuotaProjectInterface) {
+ return $this->fetcher->getQuotaProject();
+ }
+ return null;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Middleware/ProxyAuthTokenMiddleware.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Middleware/ProxyAuthTokenMiddleware.php
new file mode 100755
index 00000000..46686177
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Middleware/ProxyAuthTokenMiddleware.php
@@ -0,0 +1,130 @@
+'
+ */
+class ProxyAuthTokenMiddleware
+{
+ /**
+ * @var callable
+ */
+ private $httpHandler;
+ /**
+ * @var FetchAuthTokenInterface
+ */
+ private $fetcher;
+ /**
+ * @var ?callable
+ */
+ private $tokenCallback;
+ /**
+ * Creates a new ProxyAuthTokenMiddleware.
+ *
+ * @param FetchAuthTokenInterface $fetcher is used to fetch the auth token
+ * @param callable $httpHandler (optional) callback which delivers psr7 request
+ * @param callable $tokenCallback (optional) function to be called when a new token is fetched.
+ */
+ public function __construct(FetchAuthTokenInterface $fetcher, ?callable $httpHandler = null, ?callable $tokenCallback = null)
+ {
+ $this->fetcher = $fetcher;
+ $this->httpHandler = $httpHandler;
+ $this->tokenCallback = $tokenCallback;
+ }
+ /**
+ * Updates the request with an Authorization header when auth is 'google_auth'.
+ *
+ * use Google\Auth\Middleware\ProxyAuthTokenMiddleware;
+ * use Google\Auth\OAuth2;
+ * use GuzzleHttp\Client;
+ * use GuzzleHttp\HandlerStack;
+ *
+ * $config = [...];
+ * $oauth2 = new OAuth2($config)
+ * $middleware = new ProxyAuthTokenMiddleware($oauth2);
+ * $stack = HandlerStack::create();
+ * $stack->push($middleware);
+ *
+ * $client = new Client([
+ * 'handler' => $stack,
+ * 'base_uri' => 'https://www.googleapis.com/taskqueue/v1beta2/projects/',
+ * 'proxy_auth' => 'google_auth' // authorize all requests
+ * ]);
+ *
+ * $res = $client->get('myproject/taskqueues/myqueue');
+ *
+ * @param callable $handler
+ * @return \Closure
+ */
+ public function __invoke(callable $handler)
+ {
+ return function (RequestInterface $request, array $options) use($handler) {
+ // Requests using "proxy_auth"="google_auth" will be authorized.
+ if (!isset($options['proxy_auth']) || $options['proxy_auth'] !== 'google_auth') {
+ return $handler($request, $options);
+ }
+ $request = $request->withHeader('proxy-authorization', 'Bearer ' . $this->fetchToken());
+ if ($quotaProject = $this->getQuotaProject()) {
+ $request = $request->withHeader(GetQuotaProjectInterface::X_GOOG_USER_PROJECT_HEADER, $quotaProject);
+ }
+ return $handler($request, $options);
+ };
+ }
+ /**
+ * Call fetcher to fetch the token.
+ *
+ * @return string|null
+ */
+ private function fetchToken()
+ {
+ $auth_tokens = $this->fetcher->fetchAuthToken($this->httpHandler);
+ if (\array_key_exists('access_token', $auth_tokens)) {
+ // notify the callback if applicable
+ if ($this->tokenCallback) {
+ \call_user_func($this->tokenCallback, $this->fetcher->getCacheKey(), $auth_tokens['access_token']);
+ }
+ return $auth_tokens['access_token'];
+ }
+ if (\array_key_exists('id_token', $auth_tokens)) {
+ return $auth_tokens['id_token'];
+ }
+ return null;
+ }
+ /**
+ * @return string|null;
+ */
+ private function getQuotaProject()
+ {
+ if ($this->fetcher instanceof GetQuotaProjectInterface) {
+ return $this->fetcher->getQuotaProject();
+ }
+ return null;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Middleware/ScopedAccessTokenMiddleware.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Middleware/ScopedAccessTokenMiddleware.php
new file mode 100755
index 00000000..c8e1391b
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Middleware/ScopedAccessTokenMiddleware.php
@@ -0,0 +1,140 @@
+'
+ */
+class ScopedAccessTokenMiddleware
+{
+ use CacheTrait;
+ const DEFAULT_CACHE_LIFETIME = 1500;
+ /**
+ * @var callable
+ */
+ private $tokenFunc;
+ /**
+ * @var array|string
+ */
+ private $scopes;
+ /**
+ * Creates a new ScopedAccessTokenMiddleware.
+ *
+ * @param callable $tokenFunc a token generator function
+ * @param array|string $scopes the token authentication scopes
+ * @param array $cacheConfig configuration for the cache when it's present
+ * @param CacheItemPoolInterface $cache an implementation of CacheItemPoolInterface
+ */
+ public function __construct(callable $tokenFunc, $scopes, ?array $cacheConfig = null, ?CacheItemPoolInterface $cache = null)
+ {
+ $this->tokenFunc = $tokenFunc;
+ if (!(\is_string($scopes) || \is_array($scopes))) {
+ throw new \InvalidArgumentException('wants scope should be string or array');
+ }
+ $this->scopes = $scopes;
+ if (!\is_null($cache)) {
+ $this->cache = $cache;
+ $this->cacheConfig = \array_merge(['lifetime' => self::DEFAULT_CACHE_LIFETIME, 'prefix' => ''], $cacheConfig);
+ }
+ }
+ /**
+ * Updates the request with an Authorization header when auth is 'scoped'.
+ *
+ * E.g this could be used to authenticate using the AppEngine
+ * AppIdentityService.
+ *
+ * use google\appengine\api\app_identity\AppIdentityService;
+ * use Google\Auth\Middleware\ScopedAccessTokenMiddleware;
+ * use GuzzleHttp\Client;
+ * use GuzzleHttp\HandlerStack;
+ *
+ * $scope = 'https://www.googleapis.com/auth/taskqueue'
+ * $middleware = new ScopedAccessTokenMiddleware(
+ * 'AppIdentityService::getAccessToken',
+ * $scope,
+ * [ 'prefix' => 'Google\Auth\ScopedAccessToken::' ],
+ * $cache = new Memcache()
+ * );
+ * $stack = HandlerStack::create();
+ * $stack->push($middleware);
+ *
+ * $client = new Client([
+ * 'handler' => $stack,
+ * 'base_url' => 'https://www.googleapis.com/taskqueue/v1beta2/projects/',
+ * 'auth' => 'scoped' // authorize all requests
+ * ]);
+ *
+ * $res = $client->get('myproject/taskqueues/myqueue');
+ *
+ * @param callable $handler
+ * @return \Closure
+ */
+ public function __invoke(callable $handler)
+ {
+ return function (RequestInterface $request, array $options) use($handler) {
+ // Requests using "auth"="scoped" will be authorized.
+ if (!isset($options['auth']) || $options['auth'] !== 'scoped') {
+ return $handler($request, $options);
+ }
+ $request = $request->withHeader('authorization', 'Bearer ' . $this->fetchToken());
+ return $handler($request, $options);
+ };
+ }
+ /**
+ * @return string
+ */
+ private function getCacheKey()
+ {
+ $key = null;
+ if (\is_string($this->scopes)) {
+ $key .= $this->scopes;
+ } elseif (\is_array($this->scopes)) {
+ $key .= \implode(':', $this->scopes);
+ }
+ return $key;
+ }
+ /**
+ * Determine if token is available in the cache, if not call tokenFunc to
+ * fetch it.
+ *
+ * @return string
+ */
+ private function fetchToken()
+ {
+ $cacheKey = $this->getCacheKey();
+ $cached = $this->getCachedValue($cacheKey);
+ if (!empty($cached)) {
+ return $cached;
+ }
+ $token = \call_user_func($this->tokenFunc, $this->scopes);
+ $this->setCachedValue($cacheKey, $token);
+ return $token;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Middleware/SimpleMiddleware.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Middleware/SimpleMiddleware.php
new file mode 100755
index 00000000..c7d83129
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/Middleware/SimpleMiddleware.php
@@ -0,0 +1,86 @@
+
+ */
+ private $config;
+ /**
+ * Create a new Simple plugin.
+ *
+ * The configuration array expects one option
+ * - key: required, otherwise InvalidArgumentException is thrown
+ *
+ * @param array $config Configuration array
+ */
+ public function __construct(array $config)
+ {
+ if (!isset($config['key'])) {
+ throw new \InvalidArgumentException('requires a key to have been set');
+ }
+ $this->config = \array_merge(['key' => null], $config);
+ }
+ /**
+ * Updates the request query with the developer key if auth is set to simple.
+ *
+ * use Google\Auth\Middleware\SimpleMiddleware;
+ * use GuzzleHttp\Client;
+ * use GuzzleHttp\HandlerStack;
+ *
+ * $my_key = 'is not the same as yours';
+ * $middleware = new SimpleMiddleware(['key' => $my_key]);
+ * $stack = HandlerStack::create();
+ * $stack->push($middleware);
+ *
+ * $client = new Client([
+ * 'handler' => $stack,
+ * 'base_uri' => 'https://www.googleapis.com/discovery/v1/',
+ * 'auth' => 'simple'
+ * ]);
+ *
+ * $res = $client->get('drive/v2/rest');
+ *
+ * @param callable $handler
+ * @return \Closure
+ */
+ public function __invoke(callable $handler)
+ {
+ return function (RequestInterface $request, array $options) use($handler) {
+ // Requests using "auth"="scoped" will be authorized.
+ if (!isset($options['auth']) || $options['auth'] !== 'simple') {
+ return $handler($request, $options);
+ }
+ $query = Query::parse($request->getUri()->getQuery());
+ $params = \array_merge($query, $this->config);
+ $uri = $request->getUri()->withQuery(Query::build($params));
+ $request = $request->withUri($uri);
+ return $handler($request, $options);
+ };
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/OAuth2.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/OAuth2.php
new file mode 100755
index 00000000..27041922
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/OAuth2.php
@@ -0,0 +1,1520 @@
+
+ */
+ public static $knownSigningAlgorithms = ['HS256', 'HS512', 'HS384', 'RS256'];
+ /**
+ * The well known grant types.
+ *
+ * @var array
+ */
+ public static $knownGrantTypes = ['authorization_code', 'refresh_token', 'password', 'client_credentials'];
+ /**
+ * - authorizationUri
+ * The authorization server's HTTP endpoint capable of
+ * authenticating the end-user and obtaining authorization.
+ *
+ * @var ?UriInterface
+ */
+ private $authorizationUri;
+ /**
+ * - tokenCredentialUri
+ * The authorization server's HTTP endpoint capable of issuing
+ * tokens and refreshing expired tokens.
+ *
+ * @var UriInterface
+ */
+ private $tokenCredentialUri;
+ /**
+ * The redirection URI used in the initial request.
+ *
+ * @var ?string
+ */
+ private $redirectUri;
+ /**
+ * A unique identifier issued to the client to identify itself to the
+ * authorization server.
+ *
+ * @var string
+ */
+ private $clientId;
+ /**
+ * A shared symmetric secret issued by the authorization server, which is
+ * used to authenticate the client.
+ *
+ * @var string
+ */
+ private $clientSecret;
+ /**
+ * The resource owner's username.
+ *
+ * @var ?string
+ */
+ private $username;
+ /**
+ * The resource owner's password.
+ *
+ * @var ?string
+ */
+ private $password;
+ /**
+ * The scope of the access request, expressed either as an Array or as a
+ * space-delimited string.
+ *
+ * @var ?array
+ */
+ private $scope;
+ /**
+ * An arbitrary string designed to allow the client to maintain state.
+ *
+ * @var string
+ */
+ private $state;
+ /**
+ * The authorization code issued to this client.
+ *
+ * Only used by the authorization code access grant type.
+ *
+ * @var ?string
+ */
+ private $code;
+ /**
+ * The issuer ID when using assertion profile.
+ *
+ * @var ?string
+ */
+ private $issuer;
+ /**
+ * The target audience for assertions.
+ *
+ * @var string
+ */
+ private $audience;
+ /**
+ * The target sub when issuing assertions.
+ *
+ * @var string
+ */
+ private $sub;
+ /**
+ * The number of seconds assertions are valid for.
+ *
+ * @var int
+ */
+ private $expiry;
+ /**
+ * The signing key when using assertion profile.
+ *
+ * @var ?string
+ */
+ private $signingKey;
+ /**
+ * The signing key id when using assertion profile. Param kid in jwt header
+ *
+ * @var string
+ */
+ private $signingKeyId;
+ /**
+ * The signing algorithm when using an assertion profile.
+ *
+ * @var ?string
+ */
+ private $signingAlgorithm;
+ /**
+ * The refresh token associated with the access token to be refreshed.
+ *
+ * @var ?string
+ */
+ private $refreshToken;
+ /**
+ * The current access token.
+ *
+ * @var string
+ */
+ private $accessToken;
+ /**
+ * The current ID token.
+ *
+ * @var string
+ */
+ private $idToken;
+ /**
+ * The scopes granted to the current access token
+ *
+ * @var string
+ */
+ private $grantedScope;
+ /**
+ * The lifetime in seconds of the current access token.
+ *
+ * @var ?int
+ */
+ private $expiresIn;
+ /**
+ * The expiration time of the access token as a number of seconds since the
+ * unix epoch.
+ *
+ * @var ?int
+ */
+ private $expiresAt;
+ /**
+ * The issue time of the access token as a number of seconds since the unix
+ * epoch.
+ *
+ * @var ?int
+ */
+ private $issuedAt;
+ /**
+ * The current grant type.
+ *
+ * @var ?string
+ */
+ private $grantType;
+ /**
+ * When using an extension grant type, this is the set of parameters used by
+ * that extension.
+ *
+ * @var array
+ */
+ private $extensionParams;
+ /**
+ * When using the toJwt function, these claims will be added to the JWT
+ * payload.
+ *
+ * @var array
+ */
+ private $additionalClaims;
+ /**
+ * The code verifier for PKCE for OAuth 2.0. When set, the authorization
+ * URI will contain the Code Challenge and Code Challenge Method querystring
+ * parameters, and the token URI will contain the Code Verifier parameter.
+ *
+ * @see https://datatracker.ietf.org/doc/html/rfc7636
+ * @var ?string
+ */
+ private $codeVerifier;
+ /**
+ * For STS requests.
+ * A URI that indicates the target service or resource where the client
+ * intends to use the requested security token.
+ */
+ private ?string $resource;
+ /**
+ * For STS requests.
+ * A fetcher for the "subject_token", which is a security token that
+ * represents the identity of the party on behalf of whom the request is
+ * being made.
+ */
+ private ?ExternalAccountCredentialSourceInterface $subjectTokenFetcher;
+ /**
+ * For STS requests.
+ * An identifier, that indicates the type of the security token in the
+ * subjectToken parameter.
+ */
+ private ?string $subjectTokenType;
+ /**
+ * For STS requests.
+ * A security token that represents the identity of the acting party.
+ */
+ private ?string $actorToken;
+ /**
+ * For STS requests.
+ * An identifier that indicates the type of the security token in the
+ * actorToken parameter.
+ */
+ private ?string $actorTokenType;
+ /**
+ * From STS response.
+ * An identifier for the representation of the issued security token.
+ */
+ private ?string $issuedTokenType = null;
+ /**
+ * From STS response.
+ * An identifier for the representation of the issued security token.
+ *
+ * @var array
+ */
+ private array $additionalOptions;
+ /**
+ * Create a new OAuthCredentials.
+ *
+ * The configuration array accepts various options
+ *
+ * - authorizationUri
+ * The authorization server's HTTP endpoint capable of
+ * authenticating the end-user and obtaining authorization.
+ *
+ * - tokenCredentialUri
+ * The authorization server's HTTP endpoint capable of issuing
+ * tokens and refreshing expired tokens.
+ *
+ * - clientId
+ * A unique identifier issued to the client to identify itself to the
+ * authorization server.
+ *
+ * - clientSecret
+ * A shared symmetric secret issued by the authorization server,
+ * which is used to authenticate the client.
+ *
+ * - scope
+ * The scope of the access request, expressed either as an Array
+ * or as a space-delimited String.
+ *
+ * - state
+ * An arbitrary string designed to allow the client to maintain state.
+ *
+ * - redirectUri
+ * The redirection URI used in the initial request.
+ *
+ * - username
+ * The resource owner's username.
+ *
+ * - password
+ * The resource owner's password.
+ *
+ * - issuer
+ * Issuer ID when using assertion profile
+ *
+ * - audience
+ * Target audience for assertions
+ *
+ * - expiry
+ * Number of seconds assertions are valid for
+ *
+ * - signingKey
+ * Signing key when using assertion profile
+ *
+ * - signingKeyId
+ * Signing key id when using assertion profile
+ *
+ * - refreshToken
+ * The refresh token associated with the access token
+ * to be refreshed.
+ *
+ * - accessToken
+ * The current access token for this client.
+ *
+ * - idToken
+ * The current ID token for this client.
+ *
+ * - extensionParams
+ * When using an extension grant type, this is the set of parameters used
+ * by that extension.
+ *
+ * - codeVerifier
+ * The code verifier for PKCE for OAuth 2.0.
+ *
+ * - resource
+ * The target service or resource where the client ntends to use the
+ * requested security token.
+ *
+ * - subjectTokenFetcher
+ * A fetcher for the "subject_token", which is a security token that
+ * represents the identity of the party on behalf of whom the request is
+ * being made.
+ *
+ * - subjectTokenType
+ * An identifier that indicates the type of the security token in the
+ * subjectToken parameter.
+ *
+ * - actorToken
+ * A security token that represents the identity of the acting party.
+ *
+ * - actorTokenType
+ * An identifier for the representation of the issued security token.
+ *
+ * @param array $config Configuration array
+ */
+ public function __construct(array $config)
+ {
+ $opts = \array_merge(['expiry' => self::DEFAULT_EXPIRY_SECONDS, 'extensionParams' => [], 'authorizationUri' => null, 'redirectUri' => null, 'tokenCredentialUri' => null, 'state' => null, 'username' => null, 'password' => null, 'clientId' => null, 'clientSecret' => null, 'issuer' => null, 'sub' => null, 'audience' => null, 'signingKey' => null, 'signingKeyId' => null, 'signingAlgorithm' => null, 'scope' => null, 'additionalClaims' => [], 'codeVerifier' => null, 'resource' => null, 'subjectTokenFetcher' => null, 'subjectTokenType' => null, 'actorToken' => null, 'actorTokenType' => null, 'additionalOptions' => []], $config);
+ $this->setAuthorizationUri($opts['authorizationUri']);
+ $this->setRedirectUri($opts['redirectUri']);
+ $this->setTokenCredentialUri($opts['tokenCredentialUri']);
+ $this->setState($opts['state']);
+ $this->setUsername($opts['username']);
+ $this->setPassword($opts['password']);
+ $this->setClientId($opts['clientId']);
+ $this->setClientSecret($opts['clientSecret']);
+ $this->setIssuer($opts['issuer']);
+ $this->setSub($opts['sub']);
+ $this->setExpiry($opts['expiry']);
+ $this->setAudience($opts['audience']);
+ $this->setSigningKey($opts['signingKey']);
+ $this->setSigningKeyId($opts['signingKeyId']);
+ $this->setSigningAlgorithm($opts['signingAlgorithm']);
+ $this->setScope($opts['scope']);
+ $this->setExtensionParams($opts['extensionParams']);
+ $this->setAdditionalClaims($opts['additionalClaims']);
+ $this->setCodeVerifier($opts['codeVerifier']);
+ // for STS
+ $this->resource = $opts['resource'];
+ $this->subjectTokenFetcher = $opts['subjectTokenFetcher'];
+ $this->subjectTokenType = $opts['subjectTokenType'];
+ $this->actorToken = $opts['actorToken'];
+ $this->actorTokenType = $opts['actorTokenType'];
+ $this->additionalOptions = $opts['additionalOptions'];
+ $this->updateToken($opts);
+ }
+ /**
+ * Verifies the idToken if present.
+ *
+ * - if none is present, return null
+ * - if present, but invalid, raises DomainException.
+ * - otherwise returns the payload in the idtoken as a PHP object.
+ *
+ * The behavior of this method varies depending on the version of
+ * `firebase/php-jwt` you are using. In versions 6.0 and above, you cannot
+ * provide multiple $allowed_algs, and instead must provide an array of Key
+ * objects as the $publicKey.
+ *
+ * @param string|Key|Key[] $publicKey The public key to use to authenticate the token
+ * @param string|array $allowed_algs algorithm or array of supported verification algorithms.
+ * Providing more than one algorithm will throw an exception.
+ * @throws \DomainException if the token is missing an audience.
+ * @throws \DomainException if the audience does not match the one set in
+ * the OAuth2 class instance.
+ * @throws \UnexpectedValueException If the token is invalid
+ * @throws \InvalidArgumentException If more than one value for allowed_algs is supplied
+ * @throws \Firebase\JWT\SignatureInvalidException If the signature is invalid.
+ * @throws \Firebase\JWT\BeforeValidException If the token is not yet valid.
+ * @throws \Firebase\JWT\ExpiredException If the token has expired.
+ * @return null|object
+ */
+ public function verifyIdToken($publicKey = null, $allowed_algs = [])
+ {
+ $idToken = $this->getIdToken();
+ if (\is_null($idToken)) {
+ return null;
+ }
+ $resp = $this->jwtDecode($idToken, $publicKey, $allowed_algs);
+ if (!\property_exists($resp, 'aud')) {
+ throw new \DomainException('No audience found the id token');
+ }
+ if ($resp->aud != $this->getAudience()) {
+ throw new \DomainException('Wrong audience present in the id token');
+ }
+ return $resp;
+ }
+ /**
+ * Obtains the encoded jwt from the instance data.
+ *
+ * @param array $config array optional configuration parameters
+ * @return string
+ */
+ public function toJwt(array $config = [])
+ {
+ if (\is_null($this->getSigningKey())) {
+ throw new \DomainException('No signing key available');
+ }
+ if (\is_null($this->getSigningAlgorithm())) {
+ throw new \DomainException('No signing algorithm specified');
+ }
+ $now = \time();
+ $opts = \array_merge(['skew' => self::DEFAULT_SKEW_SECONDS], $config);
+ $assertion = ['iss' => $this->getIssuer(), 'exp' => $now + $this->getExpiry(), 'iat' => $now - $opts['skew']];
+ foreach ($assertion as $k => $v) {
+ if (\is_null($v)) {
+ throw new \DomainException($k . ' should not be null');
+ }
+ }
+ if (!\is_null($this->getAudience())) {
+ $assertion['aud'] = $this->getAudience();
+ }
+ if (!\is_null($this->getScope())) {
+ $assertion['scope'] = $this->getScope();
+ }
+ if (empty($assertion['scope']) && empty($assertion['aud'])) {
+ throw new \DomainException('one of scope or aud should not be null');
+ }
+ if (!\is_null($this->getSub())) {
+ $assertion['sub'] = $this->getSub();
+ }
+ $assertion += $this->getAdditionalClaims();
+ return JWT::encode($assertion, $this->getSigningKey(), $this->getSigningAlgorithm(), $this->getSigningKeyId());
+ }
+ /**
+ * Generates a request for token credentials.
+ *
+ * @param callable $httpHandler callback which delivers psr7 request
+ * @return RequestInterface the authorization Url.
+ */
+ public function generateCredentialsRequest(?callable $httpHandler = null)
+ {
+ $uri = $this->getTokenCredentialUri();
+ if (\is_null($uri)) {
+ throw new \DomainException('No token credential URI was set.');
+ }
+ $grantType = $this->getGrantType();
+ $params = ['grant_type' => $grantType];
+ switch ($grantType) {
+ case 'authorization_code':
+ $params['code'] = $this->getCode();
+ $params['redirect_uri'] = $this->getRedirectUri();
+ if ($this->codeVerifier) {
+ $params['code_verifier'] = $this->codeVerifier;
+ }
+ $this->addClientCredentials($params);
+ break;
+ case 'password':
+ $params['username'] = $this->getUsername();
+ $params['password'] = $this->getPassword();
+ $this->addClientCredentials($params);
+ break;
+ case 'refresh_token':
+ $params['refresh_token'] = $this->getRefreshToken();
+ $this->addClientCredentials($params);
+ break;
+ case self::JWT_URN:
+ $params['assertion'] = $this->toJwt();
+ break;
+ case self::STS_URN:
+ $token = $this->subjectTokenFetcher->fetchSubjectToken($httpHandler);
+ $params['subject_token'] = $token;
+ $params['subject_token_type'] = $this->subjectTokenType;
+ $params += \array_filter(['resource' => $this->resource, 'audience' => $this->audience, 'scope' => $this->getScope(), 'requested_token_type' => self::STS_REQUESTED_TOKEN_TYPE, 'actor_token' => $this->actorToken, 'actor_token_type' => $this->actorTokenType]);
+ if ($this->additionalOptions) {
+ $params['options'] = \json_encode($this->additionalOptions);
+ }
+ break;
+ default:
+ if (!\is_null($this->getRedirectUri())) {
+ # Grant type was supposed to be 'authorization_code', as there
+ # is a redirect URI.
+ throw new \DomainException('Missing authorization code');
+ }
+ unset($params['grant_type']);
+ if (!\is_null($grantType)) {
+ $params['grant_type'] = $grantType;
+ }
+ $params = \array_merge($params, $this->getExtensionParams());
+ }
+ $headers = ['Cache-Control' => 'no-store', 'Content-Type' => 'application/x-www-form-urlencoded'];
+ return new Request('POST', $uri, $headers, Query::build($params));
+ }
+ /**
+ * Fetches the auth tokens based on the current state.
+ *
+ * @param callable $httpHandler callback which delivers psr7 request
+ * @return array the response
+ */
+ public function fetchAuthToken(?callable $httpHandler = null)
+ {
+ if (\is_null($httpHandler)) {
+ $httpHandler = HttpHandlerFactory::build(HttpClientCache::getHttpClient());
+ }
+ $response = $httpHandler($this->generateCredentialsRequest($httpHandler));
+ $credentials = $this->parseTokenResponse($response);
+ $this->updateToken($credentials);
+ if (isset($credentials['scope'])) {
+ $this->setGrantedScope($credentials['scope']);
+ }
+ return $credentials;
+ }
+ /**
+ * Obtains a key that can used to cache the results of #fetchAuthToken.
+ *
+ * The key is derived from the scopes.
+ *
+ * @return ?string a key that may be used to cache the auth token.
+ */
+ public function getCacheKey()
+ {
+ if (\is_array($this->scope)) {
+ return \implode(':', $this->scope);
+ }
+ if ($this->audience) {
+ return $this->audience;
+ }
+ // If scope has not set, return null to indicate no caching.
+ return null;
+ }
+ /**
+ * Parses the fetched tokens.
+ *
+ * @param ResponseInterface $resp the response.
+ * @return array the tokens parsed from the response body.
+ * @throws \Exception
+ */
+ public function parseTokenResponse(ResponseInterface $resp)
+ {
+ $body = (string) $resp->getBody();
+ if ($resp->hasHeader('Content-Type') && $resp->getHeaderLine('Content-Type') == 'application/x-www-form-urlencoded') {
+ $res = [];
+ \parse_str($body, $res);
+ return $res;
+ }
+ // Assume it's JSON; if it's not throw an exception
+ if (null === ($res = \json_decode($body, \true))) {
+ throw new \Exception('Invalid JSON response');
+ }
+ return $res;
+ }
+ /**
+ * Updates an OAuth 2.0 client.
+ *
+ * Example:
+ * ```
+ * $oauth->updateToken([
+ * 'refresh_token' => 'n4E9O119d',
+ * 'access_token' => 'FJQbwq9',
+ * 'expires_in' => 3600
+ * ]);
+ * ```
+ *
+ * @param array $config
+ * The configuration parameters related to the token.
+ *
+ * - refresh_token
+ * The refresh token associated with the access token
+ * to be refreshed.
+ *
+ * - access_token
+ * The current access token for this client.
+ *
+ * - id_token
+ * The current ID token for this client.
+ *
+ * - expires_in
+ * The time in seconds until access token expiration.
+ *
+ * - expires_at
+ * The time as an integer number of seconds since the Epoch
+ *
+ * - issued_at
+ * The timestamp that the token was issued at.
+ * @return void
+ */
+ public function updateToken(array $config)
+ {
+ $opts = \array_merge(['extensionParams' => [], 'access_token' => null, 'id_token' => null, 'expires_in' => null, 'expires_at' => null, 'issued_at' => null, 'scope' => null], $config);
+ $this->setExpiresAt($opts['expires_at']);
+ $this->setExpiresIn($opts['expires_in']);
+ // By default, the token is issued at `Time.now` when `expiresIn` is set,
+ // but this can be used to supply a more precise time.
+ if (!\is_null($opts['issued_at'])) {
+ $this->setIssuedAt($opts['issued_at']);
+ }
+ $this->setAccessToken($opts['access_token']);
+ $this->setIdToken($opts['id_token']);
+ // The refresh token should only be updated if a value is explicitly
+ // passed in, as some access token responses do not include a refresh
+ // token.
+ if (\array_key_exists('refresh_token', $opts)) {
+ $this->setRefreshToken($opts['refresh_token']);
+ }
+ // Required for STS response. An identifier for the representation of
+ // the issued security token.
+ if (\array_key_exists('issued_token_type', $opts)) {
+ $this->issuedTokenType = $opts['issued_token_type'];
+ }
+ }
+ /**
+ * Builds the authorization Uri that the user should be redirected to.
+ *
+ * @param array $config configuration options that customize the return url.
+ * @return UriInterface the authorization Url.
+ * @throws InvalidArgumentException
+ */
+ public function buildFullAuthorizationUri(array $config = [])
+ {
+ if (\is_null($this->getAuthorizationUri())) {
+ throw new InvalidArgumentException('requires an authorizationUri to have been set');
+ }
+ $params = \array_merge(['response_type' => 'code', 'access_type' => 'offline', 'client_id' => $this->clientId, 'redirect_uri' => $this->redirectUri, 'state' => $this->state, 'scope' => $this->getScope()], $config);
+ // Validate the auth_params
+ if (\is_null($params['client_id'])) {
+ throw new InvalidArgumentException('missing the required client identifier');
+ }
+ if (\is_null($params['redirect_uri'])) {
+ throw new InvalidArgumentException('missing the required redirect URI');
+ }
+ if (!empty($params['prompt']) && !empty($params['approval_prompt'])) {
+ throw new InvalidArgumentException('prompt and approval_prompt are mutually exclusive');
+ }
+ if ($this->codeVerifier) {
+ $params['code_challenge'] = $this->getCodeChallenge($this->codeVerifier);
+ $params['code_challenge_method'] = $this->getCodeChallengeMethod();
+ }
+ // Construct the uri object; return it if it is valid.
+ $result = clone $this->authorizationUri;
+ $existingParams = Query::parse($result->getQuery());
+ $result = $result->withQuery(Query::build(\array_merge($existingParams, $params)));
+ if ($result->getScheme() != 'https') {
+ throw new InvalidArgumentException('Authorization endpoint must be protected by TLS');
+ }
+ return $result;
+ }
+ /**
+ * @return string|null
+ */
+ public function getCodeVerifier() : ?string
+ {
+ return $this->codeVerifier;
+ }
+ /**
+ * A cryptographically random string that is used to correlate the
+ * authorization request to the token request.
+ *
+ * The code verifier for PKCE for OAuth 2.0. When set, the authorization
+ * URI will contain the Code Challenge and Code Challenge Method querystring
+ * parameters, and the token URI will contain the Code Verifier parameter.
+ *
+ * @see https://datatracker.ietf.org/doc/html/rfc7636
+ *
+ * @param string|null $codeVerifier
+ */
+ public function setCodeVerifier(?string $codeVerifier) : void
+ {
+ $this->codeVerifier = $codeVerifier;
+ }
+ /**
+ * Generates a random 128-character string for the "code_verifier" parameter
+ * in PKCE for OAuth 2.0. This is a cryptographically random string that is
+ * determined using random_int, hashed using "hash" and sha256, and base64
+ * encoded.
+ *
+ * When this method is called, the code verifier is set on the object.
+ *
+ * @return string
+ */
+ public function generateCodeVerifier() : string
+ {
+ return $this->codeVerifier = $this->generateRandomString(128);
+ }
+ private function getCodeChallenge(string $randomString) : string
+ {
+ return \rtrim(\strtr(\base64_encode(\hash('sha256', $randomString, \true)), '+/', '-_'), '=');
+ }
+ private function getCodeChallengeMethod() : string
+ {
+ return 'S256';
+ }
+ private function generateRandomString(int $length) : string
+ {
+ $validChars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~';
+ $validCharsLen = \strlen($validChars);
+ $str = '';
+ $i = 0;
+ while ($i++ < $length) {
+ $str .= $validChars[\random_int(0, $validCharsLen - 1)];
+ }
+ return $str;
+ }
+ /**
+ * Sets the authorization server's HTTP endpoint capable of authenticating
+ * the end-user and obtaining authorization.
+ *
+ * @param string $uri
+ * @return void
+ */
+ public function setAuthorizationUri($uri)
+ {
+ $this->authorizationUri = $this->coerceUri($uri);
+ }
+ /**
+ * Gets the authorization server's HTTP endpoint capable of authenticating
+ * the end-user and obtaining authorization.
+ *
+ * @return ?UriInterface
+ */
+ public function getAuthorizationUri()
+ {
+ return $this->authorizationUri;
+ }
+ /**
+ * Gets the authorization server's HTTP endpoint capable of issuing tokens
+ * and refreshing expired tokens.
+ *
+ * @return ?UriInterface
+ */
+ public function getTokenCredentialUri()
+ {
+ return $this->tokenCredentialUri;
+ }
+ /**
+ * Sets the authorization server's HTTP endpoint capable of issuing tokens
+ * and refreshing expired tokens.
+ *
+ * @param string $uri
+ * @return void
+ */
+ public function setTokenCredentialUri($uri)
+ {
+ $this->tokenCredentialUri = $this->coerceUri($uri);
+ }
+ /**
+ * Gets the redirection URI used in the initial request.
+ *
+ * @return ?string
+ */
+ public function getRedirectUri()
+ {
+ return $this->redirectUri;
+ }
+ /**
+ * Sets the redirection URI used in the initial request.
+ *
+ * @param ?string $uri
+ * @return void
+ */
+ public function setRedirectUri($uri)
+ {
+ if (\is_null($uri)) {
+ $this->redirectUri = null;
+ return;
+ }
+ // redirect URI must be absolute
+ if (!$this->isAbsoluteUri($uri)) {
+ // "postmessage" is a reserved URI string in Google-land
+ // @see https://developers.google.com/identity/sign-in/web/server-side-flow
+ if ('postmessage' !== (string) $uri) {
+ throw new InvalidArgumentException('Redirect URI must be absolute');
+ }
+ }
+ $this->redirectUri = (string) $uri;
+ }
+ /**
+ * Gets the scope of the access requests as a space-delimited String.
+ *
+ * @return ?string
+ */
+ public function getScope()
+ {
+ if (\is_null($this->scope)) {
+ return $this->scope;
+ }
+ return \implode(' ', $this->scope);
+ }
+ /**
+ * Sets the scope of the access request, expressed either as an Array or as
+ * a space-delimited String.
+ *
+ * @param string|array|null $scope
+ * @return void
+ * @throws InvalidArgumentException
+ */
+ public function setScope($scope)
+ {
+ if (\is_null($scope)) {
+ $this->scope = null;
+ } elseif (\is_string($scope)) {
+ $this->scope = \explode(' ', $scope);
+ } elseif (\is_array($scope)) {
+ foreach ($scope as $s) {
+ $pos = \strpos($s, ' ');
+ if ($pos !== \false) {
+ throw new InvalidArgumentException('array scope values should not contain spaces');
+ }
+ }
+ $this->scope = $scope;
+ } else {
+ throw new InvalidArgumentException('scopes should be a string or array of strings');
+ }
+ }
+ /**
+ * Gets the current grant type.
+ *
+ * @return ?string
+ */
+ public function getGrantType()
+ {
+ if (!\is_null($this->grantType)) {
+ return $this->grantType;
+ }
+ // Returns the inferred grant type, based on the current object instance
+ // state.
+ if (!\is_null($this->code)) {
+ return 'authorization_code';
+ }
+ if (!\is_null($this->refreshToken)) {
+ return 'refresh_token';
+ }
+ if (!\is_null($this->username) && !\is_null($this->password)) {
+ return 'password';
+ }
+ if (!\is_null($this->issuer) && !\is_null($this->signingKey)) {
+ return self::JWT_URN;
+ }
+ if (!\is_null($this->subjectTokenFetcher) && !\is_null($this->subjectTokenType)) {
+ return self::STS_URN;
+ }
+ return null;
+ }
+ /**
+ * Sets the current grant type.
+ *
+ * @param string $grantType
+ * @return void
+ * @throws InvalidArgumentException
+ */
+ public function setGrantType($grantType)
+ {
+ if (\in_array($grantType, self::$knownGrantTypes)) {
+ $this->grantType = $grantType;
+ } else {
+ // validate URI
+ if (!$this->isAbsoluteUri($grantType)) {
+ throw new InvalidArgumentException('invalid grant type');
+ }
+ $this->grantType = (string) $grantType;
+ }
+ }
+ /**
+ * Gets an arbitrary string designed to allow the client to maintain state.
+ *
+ * @return string
+ */
+ public function getState()
+ {
+ return $this->state;
+ }
+ /**
+ * Sets an arbitrary string designed to allow the client to maintain state.
+ *
+ * @param string $state
+ * @return void
+ */
+ public function setState($state)
+ {
+ $this->state = $state;
+ }
+ /**
+ * Gets the authorization code issued to this client.
+ *
+ * @return string
+ */
+ public function getCode()
+ {
+ return $this->code;
+ }
+ /**
+ * Sets the authorization code issued to this client.
+ *
+ * @param string $code
+ * @return void
+ */
+ public function setCode($code)
+ {
+ $this->code = $code;
+ }
+ /**
+ * Gets the resource owner's username.
+ *
+ * @return string
+ */
+ public function getUsername()
+ {
+ return $this->username;
+ }
+ /**
+ * Sets the resource owner's username.
+ *
+ * @param string $username
+ * @return void
+ */
+ public function setUsername($username)
+ {
+ $this->username = $username;
+ }
+ /**
+ * Gets the resource owner's password.
+ *
+ * @return string
+ */
+ public function getPassword()
+ {
+ return $this->password;
+ }
+ /**
+ * Sets the resource owner's password.
+ *
+ * @param string $password
+ * @return void
+ */
+ public function setPassword($password)
+ {
+ $this->password = $password;
+ }
+ /**
+ * Sets a unique identifier issued to the client to identify itself to the
+ * authorization server.
+ *
+ * @return string
+ */
+ public function getClientId()
+ {
+ return $this->clientId;
+ }
+ /**
+ * Sets a unique identifier issued to the client to identify itself to the
+ * authorization server.
+ *
+ * @param string $clientId
+ * @return void
+ */
+ public function setClientId($clientId)
+ {
+ $this->clientId = $clientId;
+ }
+ /**
+ * Gets a shared symmetric secret issued by the authorization server, which
+ * is used to authenticate the client.
+ *
+ * @return string
+ */
+ public function getClientSecret()
+ {
+ return $this->clientSecret;
+ }
+ /**
+ * Sets a shared symmetric secret issued by the authorization server, which
+ * is used to authenticate the client.
+ *
+ * @param string $clientSecret
+ * @return void
+ */
+ public function setClientSecret($clientSecret)
+ {
+ $this->clientSecret = $clientSecret;
+ }
+ /**
+ * Gets the Issuer ID when using assertion profile.
+ *
+ * @return ?string
+ */
+ public function getIssuer()
+ {
+ return $this->issuer;
+ }
+ /**
+ * Sets the Issuer ID when using assertion profile.
+ *
+ * @param string $issuer
+ * @return void
+ */
+ public function setIssuer($issuer)
+ {
+ $this->issuer = $issuer;
+ }
+ /**
+ * Gets the target sub when issuing assertions.
+ *
+ * @return ?string
+ */
+ public function getSub()
+ {
+ return $this->sub;
+ }
+ /**
+ * Sets the target sub when issuing assertions.
+ *
+ * @param string $sub
+ * @return void
+ */
+ public function setSub($sub)
+ {
+ $this->sub = $sub;
+ }
+ /**
+ * Gets the target audience when issuing assertions.
+ *
+ * @return ?string
+ */
+ public function getAudience()
+ {
+ return $this->audience;
+ }
+ /**
+ * Sets the target audience when issuing assertions.
+ *
+ * @param string $audience
+ * @return void
+ */
+ public function setAudience($audience)
+ {
+ $this->audience = $audience;
+ }
+ /**
+ * Gets the signing key when using an assertion profile.
+ *
+ * @return ?string
+ */
+ public function getSigningKey()
+ {
+ return $this->signingKey;
+ }
+ /**
+ * Sets the signing key when using an assertion profile.
+ *
+ * @param string $signingKey
+ * @return void
+ */
+ public function setSigningKey($signingKey)
+ {
+ $this->signingKey = $signingKey;
+ }
+ /**
+ * Gets the signing key id when using an assertion profile.
+ *
+ * @return ?string
+ */
+ public function getSigningKeyId()
+ {
+ return $this->signingKeyId;
+ }
+ /**
+ * Sets the signing key id when using an assertion profile.
+ *
+ * @param string $signingKeyId
+ * @return void
+ */
+ public function setSigningKeyId($signingKeyId)
+ {
+ $this->signingKeyId = $signingKeyId;
+ }
+ /**
+ * Gets the signing algorithm when using an assertion profile.
+ *
+ * @return ?string
+ */
+ public function getSigningAlgorithm()
+ {
+ return $this->signingAlgorithm;
+ }
+ /**
+ * Sets the signing algorithm when using an assertion profile.
+ *
+ * @param ?string $signingAlgorithm
+ * @return void
+ */
+ public function setSigningAlgorithm($signingAlgorithm)
+ {
+ if (\is_null($signingAlgorithm)) {
+ $this->signingAlgorithm = null;
+ } elseif (!\in_array($signingAlgorithm, self::$knownSigningAlgorithms)) {
+ throw new InvalidArgumentException('unknown signing algorithm');
+ } else {
+ $this->signingAlgorithm = $signingAlgorithm;
+ }
+ }
+ /**
+ * Gets the set of parameters used by extension when using an extension
+ * grant type.
+ *
+ * @return array
+ */
+ public function getExtensionParams()
+ {
+ return $this->extensionParams;
+ }
+ /**
+ * Sets the set of parameters used by extension when using an extension
+ * grant type.
+ *
+ * @param array $extensionParams
+ * @return void
+ */
+ public function setExtensionParams($extensionParams)
+ {
+ $this->extensionParams = $extensionParams;
+ }
+ /**
+ * Gets the number of seconds assertions are valid for.
+ *
+ * @return int
+ */
+ public function getExpiry()
+ {
+ return $this->expiry;
+ }
+ /**
+ * Sets the number of seconds assertions are valid for.
+ *
+ * @param int $expiry
+ * @return void
+ */
+ public function setExpiry($expiry)
+ {
+ $this->expiry = $expiry;
+ }
+ /**
+ * Gets the lifetime of the access token in seconds.
+ *
+ * @return int
+ */
+ public function getExpiresIn()
+ {
+ return $this->expiresIn;
+ }
+ /**
+ * Sets the lifetime of the access token in seconds.
+ *
+ * @param ?int $expiresIn
+ * @return void
+ */
+ public function setExpiresIn($expiresIn)
+ {
+ if (\is_null($expiresIn)) {
+ $this->expiresIn = null;
+ $this->issuedAt = null;
+ } else {
+ $this->issuedAt = \time();
+ $this->expiresIn = (int) $expiresIn;
+ }
+ }
+ /**
+ * Gets the time the current access token expires at.
+ *
+ * @return ?int
+ */
+ public function getExpiresAt()
+ {
+ if (!\is_null($this->expiresAt)) {
+ return $this->expiresAt;
+ }
+ if (!\is_null($this->issuedAt) && !\is_null($this->expiresIn)) {
+ return $this->issuedAt + $this->expiresIn;
+ }
+ return null;
+ }
+ /**
+ * Returns true if the acccess token has expired.
+ *
+ * @return bool
+ */
+ public function isExpired()
+ {
+ $expiration = $this->getExpiresAt();
+ $now = \time();
+ return !\is_null($expiration) && $now >= $expiration;
+ }
+ /**
+ * Sets the time the current access token expires at.
+ *
+ * @param int $expiresAt
+ * @return void
+ */
+ public function setExpiresAt($expiresAt)
+ {
+ $this->expiresAt = $expiresAt;
+ }
+ /**
+ * Gets the time the current access token was issued at.
+ *
+ * @return ?int
+ */
+ public function getIssuedAt()
+ {
+ return $this->issuedAt;
+ }
+ /**
+ * Sets the time the current access token was issued at.
+ *
+ * @param int $issuedAt
+ * @return void
+ */
+ public function setIssuedAt($issuedAt)
+ {
+ $this->issuedAt = $issuedAt;
+ }
+ /**
+ * Gets the current access token.
+ *
+ * @return ?string
+ */
+ public function getAccessToken()
+ {
+ return $this->accessToken;
+ }
+ /**
+ * Sets the current access token.
+ *
+ * @param string $accessToken
+ * @return void
+ */
+ public function setAccessToken($accessToken)
+ {
+ $this->accessToken = $accessToken;
+ }
+ /**
+ * Gets the current ID token.
+ *
+ * @return ?string
+ */
+ public function getIdToken()
+ {
+ return $this->idToken;
+ }
+ /**
+ * Sets the current ID token.
+ *
+ * @param string $idToken
+ * @return void
+ */
+ public function setIdToken($idToken)
+ {
+ $this->idToken = $idToken;
+ }
+ /**
+ * Get the granted space-separated scopes (if they exist) for the last
+ * fetched token.
+ *
+ * @return string|null
+ */
+ public function getGrantedScope()
+ {
+ return $this->grantedScope;
+ }
+ /**
+ * Sets the current ID token.
+ *
+ * @param string $grantedScope
+ * @return void
+ */
+ public function setGrantedScope($grantedScope)
+ {
+ $this->grantedScope = $grantedScope;
+ }
+ /**
+ * Gets the refresh token associated with the current access token.
+ *
+ * @return ?string
+ */
+ public function getRefreshToken()
+ {
+ return $this->refreshToken;
+ }
+ /**
+ * Sets the refresh token associated with the current access token.
+ *
+ * @param string $refreshToken
+ * @return void
+ */
+ public function setRefreshToken($refreshToken)
+ {
+ $this->refreshToken = $refreshToken;
+ }
+ /**
+ * Sets additional claims to be included in the JWT token
+ *
+ * @param array $additionalClaims
+ * @return void
+ */
+ public function setAdditionalClaims(array $additionalClaims)
+ {
+ $this->additionalClaims = $additionalClaims;
+ }
+ /**
+ * Gets the additional claims to be included in the JWT token.
+ *
+ * @return array
+ */
+ public function getAdditionalClaims()
+ {
+ return $this->additionalClaims;
+ }
+ /**
+ * Gets the additional claims to be included in the JWT token.
+ *
+ * @return ?string
+ */
+ public function getIssuedTokenType()
+ {
+ return $this->issuedTokenType;
+ }
+ /**
+ * The expiration of the last received token.
+ *
+ * @return array|null
+ */
+ public function getLastReceivedToken()
+ {
+ if ($token = $this->getAccessToken()) {
+ // the bare necessity of an auth token
+ $authToken = ['access_token' => $token, 'expires_at' => $this->getExpiresAt()];
+ } elseif ($idToken = $this->getIdToken()) {
+ $authToken = ['id_token' => $idToken, 'expires_at' => $this->getExpiresAt()];
+ } else {
+ return null;
+ }
+ if ($expiresIn = $this->getExpiresIn()) {
+ $authToken['expires_in'] = $expiresIn;
+ }
+ if ($issuedAt = $this->getIssuedAt()) {
+ $authToken['issued_at'] = $issuedAt;
+ }
+ if ($refreshToken = $this->getRefreshToken()) {
+ $authToken['refresh_token'] = $refreshToken;
+ }
+ return $authToken;
+ }
+ /**
+ * Get the client ID.
+ *
+ * Alias of {@see Google\Auth\OAuth2::getClientId()}.
+ *
+ * @param callable $httpHandler
+ * @return string
+ * @access private
+ */
+ public function getClientName(?callable $httpHandler = null)
+ {
+ return $this->getClientId();
+ }
+ /**
+ * @todo handle uri as array
+ *
+ * @param ?string $uri
+ * @return null|UriInterface
+ */
+ private function coerceUri($uri)
+ {
+ if (\is_null($uri)) {
+ return null;
+ }
+ return Utils::uriFor($uri);
+ }
+ /**
+ * @param string $idToken
+ * @param Key|Key[]|string|string[] $publicKey
+ * @param string|string[] $allowedAlgs
+ * @return object
+ */
+ private function jwtDecode($idToken, $publicKey, $allowedAlgs)
+ {
+ $keys = $this->getFirebaseJwtKeys($publicKey, $allowedAlgs);
+ // Default exception if none are caught. We are using the same exception
+ // class and message from firebase/php-jwt to preserve backwards
+ // compatibility.
+ $e = new \InvalidArgumentException('Key may not be empty');
+ foreach ($keys as $key) {
+ try {
+ return JWT::decode($idToken, $key);
+ } catch (\Exception $e) {
+ // try next alg
+ }
+ }
+ throw $e;
+ }
+ /**
+ * @param Key|Key[]|string|string[] $publicKey
+ * @param string|string[] $allowedAlgs
+ * @return Key[]
+ */
+ private function getFirebaseJwtKeys($publicKey, $allowedAlgs)
+ {
+ // If $publicKey is instance of Key, return it
+ if ($publicKey instanceof Key) {
+ return [$publicKey];
+ }
+ // If $allowedAlgs is empty, $publicKey must be Key or Key[].
+ if (empty($allowedAlgs)) {
+ $keys = [];
+ foreach ((array) $publicKey as $kid => $pubKey) {
+ if (!$pubKey instanceof Key) {
+ throw new \InvalidArgumentException(\sprintf('When allowed algorithms is empty, the public key must' . 'be an instance of %s or an array of %s objects', Key::class, Key::class));
+ }
+ $keys[$kid] = $pubKey;
+ }
+ return $keys;
+ }
+ $allowedAlg = null;
+ if (\is_string($allowedAlgs)) {
+ $allowedAlg = $allowedAlgs;
+ } elseif (\is_array($allowedAlgs)) {
+ if (\count($allowedAlgs) > 1) {
+ throw new \InvalidArgumentException('To have multiple allowed algorithms, You must provide an' . ' array of Firebase\\JWT\\Key objects.' . ' See https://github.com/firebase/php-jwt for more information.');
+ }
+ $allowedAlg = \array_pop($allowedAlgs);
+ } else {
+ throw new \InvalidArgumentException('allowed algorithms must be a string or array.');
+ }
+ if (\is_array($publicKey)) {
+ // When publicKey is greater than 1, create keys with the single alg.
+ $keys = [];
+ foreach ($publicKey as $kid => $pubKey) {
+ if ($pubKey instanceof Key) {
+ $keys[$kid] = $pubKey;
+ } else {
+ $keys[$kid] = new Key($pubKey, $allowedAlg);
+ }
+ }
+ return $keys;
+ }
+ return [new Key($publicKey, $allowedAlg)];
+ }
+ /**
+ * Determines if the URI is absolute based on its scheme and host or path
+ * (RFC 3986).
+ *
+ * @param string $uri
+ * @return bool
+ */
+ private function isAbsoluteUri($uri)
+ {
+ $uri = $this->coerceUri($uri);
+ return $uri->getScheme() && ($uri->getHost() || $uri->getPath());
+ }
+ /**
+ * @param array $params
+ * @return array
+ */
+ private function addClientCredentials(&$params)
+ {
+ $clientId = $this->getClientId();
+ $clientSecret = $this->getClientSecret();
+ if ($clientId && $clientSecret) {
+ $params['client_id'] = $clientId;
+ $params['client_secret'] = $clientSecret;
+ }
+ return $params;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/ProjectIdProviderInterface.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/ProjectIdProviderInterface.php
new file mode 100755
index 00000000..0e5910d8
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/ProjectIdProviderInterface.php
@@ -0,0 +1,32 @@
+auth->getSigningKey();
+ $signedString = '';
+ if (\class_exists(phpseclib3\Crypt\RSA::class) && !$forceOpenssl) {
+ $key = PublicKeyLoader::load($privateKey);
+ $rsa = $key->withHash('sha256')->withPadding(RSA::SIGNATURE_PKCS1);
+ $signedString = $rsa->sign($stringToSign);
+ } elseif (\extension_loaded('openssl')) {
+ \openssl_sign($stringToSign, $signedString, $privateKey, 'sha256WithRSAEncryption');
+ } else {
+ // @codeCoverageIgnoreStart
+ throw new \RuntimeException('OpenSSL is not installed.');
+ }
+ // @codeCoverageIgnoreEnd
+ return \base64_encode($signedString);
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/SignBlobInterface.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/SignBlobInterface.php
new file mode 100755
index 00000000..2fdbda5e
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/SignBlobInterface.php
@@ -0,0 +1,43 @@
+ $metadata metadata hashmap
+ * @param string $authUri optional auth uri
+ * @param callable $httpHandler callback which delivers psr7 request
+ * @return array updated metadata hashmap
+ */
+ public function updateMetadata($metadata, $authUri = null, ?callable $httpHandler = null);
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/UpdateMetadataTrait.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/UpdateMetadataTrait.php
new file mode 100755
index 00000000..8d0f10d4
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/auth/src/UpdateMetadataTrait.php
@@ -0,0 +1,62 @@
+ $metadata metadata hashmap
+ * @param string $authUri optional auth uri
+ * @param callable $httpHandler callback which delivers psr7 request
+ * @return array updated metadata hashmap
+ */
+ public function updateMetadata($metadata, $authUri = null, ?callable $httpHandler = null)
+ {
+ if (isset($metadata[self::AUTH_METADATA_KEY])) {
+ // Auth metadata has already been set
+ return $metadata;
+ }
+ $result = $this->fetchAuthToken($httpHandler);
+ $metadata_copy = $metadata;
+ if (isset($result['access_token'])) {
+ $metadata_copy[self::AUTH_METADATA_KEY] = ['Bearer ' . $result['access_token']];
+ } elseif (isset($result['id_token'])) {
+ $metadata_copy[self::AUTH_METADATA_KEY] = ['Bearer ' . $result['id_token']];
+ }
+ return $metadata_copy;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/LICENSE b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/LICENSE
new file mode 100755
index 00000000..fd2375d8
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/LICENSE
@@ -0,0 +1,27 @@
+The MIT License (MIT)
+
+Copyright (c) 2011 Michael Dowling
+Copyright (c) 2012 Jeremy Lindblom
+Copyright (c) 2014 Graham Campbell
+Copyright (c) 2015 MƔrk SƔgi-KazƔr
+Copyright (c) 2015 Tobias Schultze
+Copyright (c) 2016 Tobias Nyholm
+Copyright (c) 2016 George Mponos
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/BodySummarizer.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/BodySummarizer.php
new file mode 100755
index 00000000..95fee101
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/BodySummarizer.php
@@ -0,0 +1,23 @@
+truncateAt = $truncateAt;
+ }
+ /**
+ * Returns a summarized message body.
+ */
+ public function summarize(MessageInterface $message) : ?string
+ {
+ return $this->truncateAt === null ? Psr7\Message::bodySummary($message) : Psr7\Message::bodySummary($message, $this->truncateAt);
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/BodySummarizerInterface.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/BodySummarizerInterface.php
new file mode 100755
index 00000000..17f486e5
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/BodySummarizerInterface.php
@@ -0,0 +1,12 @@
+ 'http://www.foo.com/1.0/',
+ * 'timeout' => 0,
+ * 'allow_redirects' => false,
+ * 'proxy' => '192.168.16.1:10'
+ * ]);
+ *
+ * Client configuration settings include the following options:
+ *
+ * - handler: (callable) Function that transfers HTTP requests over the
+ * wire. The function is called with a Psr7\Http\Message\RequestInterface
+ * and array of transfer options, and must return a
+ * GuzzleHttp\Promise\PromiseInterface that is fulfilled with a
+ * Psr7\Http\Message\ResponseInterface on success.
+ * If no handler is provided, a default handler will be created
+ * that enables all of the request options below by attaching all of the
+ * default middleware to the handler.
+ * - base_uri: (string|UriInterface) Base URI of the client that is merged
+ * into relative URIs. Can be a string or instance of UriInterface.
+ * - **: any request option
+ *
+ * @param array $config Client configuration settings.
+ *
+ * @see RequestOptions for a list of available request options.
+ */
+ public function __construct(array $config = [])
+ {
+ if (!isset($config['handler'])) {
+ $config['handler'] = HandlerStack::create();
+ } elseif (!\is_callable($config['handler'])) {
+ throw new InvalidArgumentException('handler must be a callable');
+ }
+ // Convert the base_uri to a UriInterface
+ if (isset($config['base_uri'])) {
+ $config['base_uri'] = Psr7\Utils::uriFor($config['base_uri']);
+ }
+ $this->configureDefaults($config);
+ }
+ /**
+ * @param string $method
+ * @param array $args
+ *
+ * @return PromiseInterface|ResponseInterface
+ *
+ * @deprecated Client::__call will be removed in guzzlehttp/guzzle:8.0.
+ */
+ public function __call($method, $args)
+ {
+ if (\count($args) < 1) {
+ throw new InvalidArgumentException('Magic request methods require a URI and optional options array');
+ }
+ $uri = $args[0];
+ $opts = $args[1] ?? [];
+ return \substr($method, -5) === 'Async' ? $this->requestAsync(\substr($method, 0, -5), $uri, $opts) : $this->request($method, $uri, $opts);
+ }
+ /**
+ * Asynchronously send an HTTP request.
+ *
+ * @param array $options Request options to apply to the given
+ * request and to the transfer. See \GuzzleHttp\RequestOptions.
+ */
+ public function sendAsync(RequestInterface $request, array $options = []) : PromiseInterface
+ {
+ // Merge the base URI into the request URI if needed.
+ $options = $this->prepareDefaults($options);
+ return $this->transfer($request->withUri($this->buildUri($request->getUri(), $options), $request->hasHeader('Host')), $options);
+ }
+ /**
+ * Send an HTTP request.
+ *
+ * @param array $options Request options to apply to the given
+ * request and to the transfer. See \GuzzleHttp\RequestOptions.
+ *
+ * @throws GuzzleException
+ */
+ public function send(RequestInterface $request, array $options = []) : ResponseInterface
+ {
+ $options[RequestOptions::SYNCHRONOUS] = \true;
+ return $this->sendAsync($request, $options)->wait();
+ }
+ /**
+ * The HttpClient PSR (PSR-18) specify this method.
+ *
+ * {@inheritDoc}
+ */
+ public function sendRequest(RequestInterface $request) : ResponseInterface
+ {
+ $options[RequestOptions::SYNCHRONOUS] = \true;
+ $options[RequestOptions::ALLOW_REDIRECTS] = \false;
+ $options[RequestOptions::HTTP_ERRORS] = \false;
+ return $this->sendAsync($request, $options)->wait();
+ }
+ /**
+ * Create and send an asynchronous HTTP request.
+ *
+ * Use an absolute path to override the base path of the client, or a
+ * relative path to append to the base path of the client. The URL can
+ * contain the query string as well. Use an array to provide a URL
+ * template and additional variables to use in the URL template expansion.
+ *
+ * @param string $method HTTP method
+ * @param string|UriInterface $uri URI object or string.
+ * @param array $options Request options to apply. See \GuzzleHttp\RequestOptions.
+ */
+ public function requestAsync(string $method, $uri = '', array $options = []) : PromiseInterface
+ {
+ $options = $this->prepareDefaults($options);
+ // Remove request modifying parameter because it can be done up-front.
+ $headers = $options['headers'] ?? [];
+ $body = $options['body'] ?? null;
+ $version = $options['version'] ?? '1.1';
+ // Merge the URI into the base URI.
+ $uri = $this->buildUri(Psr7\Utils::uriFor($uri), $options);
+ if (\is_array($body)) {
+ throw $this->invalidBody();
+ }
+ $request = new Psr7\Request($method, $uri, $headers, $body, $version);
+ // Remove the option so that they are not doubly-applied.
+ unset($options['headers'], $options['body'], $options['version']);
+ return $this->transfer($request, $options);
+ }
+ /**
+ * Create and send an HTTP request.
+ *
+ * Use an absolute path to override the base path of the client, or a
+ * relative path to append to the base path of the client. The URL can
+ * contain the query string as well.
+ *
+ * @param string $method HTTP method.
+ * @param string|UriInterface $uri URI object or string.
+ * @param array $options Request options to apply. See \GuzzleHttp\RequestOptions.
+ *
+ * @throws GuzzleException
+ */
+ public function request(string $method, $uri = '', array $options = []) : ResponseInterface
+ {
+ $options[RequestOptions::SYNCHRONOUS] = \true;
+ return $this->requestAsync($method, $uri, $options)->wait();
+ }
+ /**
+ * Get a client configuration option.
+ *
+ * These options include default request options of the client, a "handler"
+ * (if utilized by the concrete client), and a "base_uri" if utilized by
+ * the concrete client.
+ *
+ * @param string|null $option The config option to retrieve.
+ *
+ * @return mixed
+ *
+ * @deprecated Client::getConfig will be removed in guzzlehttp/guzzle:8.0.
+ */
+ public function getConfig(?string $option = null)
+ {
+ return $option === null ? $this->config : $this->config[$option] ?? null;
+ }
+ private function buildUri(UriInterface $uri, array $config) : UriInterface
+ {
+ if (isset($config['base_uri'])) {
+ $uri = Psr7\UriResolver::resolve(Psr7\Utils::uriFor($config['base_uri']), $uri);
+ }
+ if (isset($config['idn_conversion']) && $config['idn_conversion'] !== \false) {
+ $idnOptions = $config['idn_conversion'] === \true ? \IDNA_DEFAULT : $config['idn_conversion'];
+ $uri = Utils::idnUriConvert($uri, $idnOptions);
+ }
+ return $uri->getScheme() === '' && $uri->getHost() !== '' ? $uri->withScheme('http') : $uri;
+ }
+ /**
+ * Configures the default options for a client.
+ */
+ private function configureDefaults(array $config) : void
+ {
+ $defaults = ['allow_redirects' => RedirectMiddleware::$defaultSettings, 'http_errors' => \true, 'decode_content' => \true, 'verify' => \true, 'cookies' => \false, 'idn_conversion' => \false];
+ // Use the standard Linux HTTP_PROXY and HTTPS_PROXY if set.
+ // We can only trust the HTTP_PROXY environment variable in a CLI
+ // process due to the fact that PHP has no reliable mechanism to
+ // get environment variables that start with "HTTP_".
+ if (\PHP_SAPI === 'cli' && ($proxy = Utils::getenv('HTTP_PROXY'))) {
+ $defaults['proxy']['http'] = $proxy;
+ }
+ if ($proxy = Utils::getenv('HTTPS_PROXY')) {
+ $defaults['proxy']['https'] = $proxy;
+ }
+ if ($noProxy = Utils::getenv('NO_PROXY')) {
+ $cleanedNoProxy = \str_replace(' ', '', $noProxy);
+ $defaults['proxy']['no'] = \explode(',', $cleanedNoProxy);
+ }
+ $this->config = $config + $defaults;
+ if (!empty($config['cookies']) && $config['cookies'] === \true) {
+ $this->config['cookies'] = new CookieJar();
+ }
+ // Add the default user-agent header.
+ if (!isset($this->config['headers'])) {
+ $this->config['headers'] = ['User-Agent' => Utils::defaultUserAgent()];
+ } else {
+ // Add the User-Agent header if one was not already set.
+ foreach (\array_keys($this->config['headers']) as $name) {
+ if (\strtolower($name) === 'user-agent') {
+ return;
+ }
+ }
+ $this->config['headers']['User-Agent'] = Utils::defaultUserAgent();
+ }
+ }
+ /**
+ * Merges default options into the array.
+ *
+ * @param array $options Options to modify by reference
+ */
+ private function prepareDefaults(array $options) : array
+ {
+ $defaults = $this->config;
+ if (!empty($defaults['headers'])) {
+ // Default headers are only added if they are not present.
+ $defaults['_conditional'] = $defaults['headers'];
+ unset($defaults['headers']);
+ }
+ // Special handling for headers is required as they are added as
+ // conditional headers and as headers passed to a request ctor.
+ if (\array_key_exists('headers', $options)) {
+ // Allows default headers to be unset.
+ if ($options['headers'] === null) {
+ $defaults['_conditional'] = [];
+ unset($options['headers']);
+ } elseif (!\is_array($options['headers'])) {
+ throw new InvalidArgumentException('headers must be an array');
+ }
+ }
+ // Shallow merge defaults underneath options.
+ $result = $options + $defaults;
+ // Remove null values.
+ foreach ($result as $k => $v) {
+ if ($v === null) {
+ unset($result[$k]);
+ }
+ }
+ return $result;
+ }
+ /**
+ * Transfers the given request and applies request options.
+ *
+ * The URI of the request is not modified and the request options are used
+ * as-is without merging in default options.
+ *
+ * @param array $options See \GuzzleHttp\RequestOptions.
+ */
+ private function transfer(RequestInterface $request, array $options) : PromiseInterface
+ {
+ $request = $this->applyOptions($request, $options);
+ /** @var HandlerStack $handler */
+ $handler = $options['handler'];
+ try {
+ return P\Create::promiseFor($handler($request, $options));
+ } catch (\Exception $e) {
+ return P\Create::rejectionFor($e);
+ }
+ }
+ /**
+ * Applies the array of request options to a request.
+ */
+ private function applyOptions(RequestInterface $request, array &$options) : RequestInterface
+ {
+ $modify = ['set_headers' => []];
+ if (isset($options['headers'])) {
+ if (\array_keys($options['headers']) === \range(0, \count($options['headers']) - 1)) {
+ throw new InvalidArgumentException('The headers array must have header name as keys.');
+ }
+ $modify['set_headers'] = $options['headers'];
+ unset($options['headers']);
+ }
+ if (isset($options['form_params'])) {
+ if (isset($options['multipart'])) {
+ throw new InvalidArgumentException('You cannot use ' . 'form_params and multipart at the same time. Use the ' . 'form_params option if you want to send application/' . 'x-www-form-urlencoded requests, and the multipart ' . 'option to send multipart/form-data requests.');
+ }
+ $options['body'] = \http_build_query($options['form_params'], '', '&');
+ unset($options['form_params']);
+ // Ensure that we don't have the header in different case and set the new value.
+ $options['_conditional'] = Psr7\Utils::caselessRemove(['Content-Type'], $options['_conditional']);
+ $options['_conditional']['Content-Type'] = 'application/x-www-form-urlencoded';
+ }
+ if (isset($options['multipart'])) {
+ $options['body'] = new Psr7\MultipartStream($options['multipart']);
+ unset($options['multipart']);
+ }
+ if (isset($options['json'])) {
+ $options['body'] = Utils::jsonEncode($options['json']);
+ unset($options['json']);
+ // Ensure that we don't have the header in different case and set the new value.
+ $options['_conditional'] = Psr7\Utils::caselessRemove(['Content-Type'], $options['_conditional']);
+ $options['_conditional']['Content-Type'] = 'application/json';
+ }
+ if (!empty($options['decode_content']) && $options['decode_content'] !== \true) {
+ // Ensure that we don't have the header in different case and set the new value.
+ $options['_conditional'] = Psr7\Utils::caselessRemove(['Accept-Encoding'], $options['_conditional']);
+ $modify['set_headers']['Accept-Encoding'] = $options['decode_content'];
+ }
+ if (isset($options['body'])) {
+ if (\is_array($options['body'])) {
+ throw $this->invalidBody();
+ }
+ $modify['body'] = Psr7\Utils::streamFor($options['body']);
+ unset($options['body']);
+ }
+ if (!empty($options['auth']) && \is_array($options['auth'])) {
+ $value = $options['auth'];
+ $type = isset($value[2]) ? \strtolower($value[2]) : 'basic';
+ switch ($type) {
+ case 'basic':
+ // Ensure that we don't have the header in different case and set the new value.
+ $modify['set_headers'] = Psr7\Utils::caselessRemove(['Authorization'], $modify['set_headers']);
+ $modify['set_headers']['Authorization'] = 'Basic ' . \base64_encode("{$value[0]}:{$value[1]}");
+ break;
+ case 'digest':
+ // @todo: Do not rely on curl
+ $options['curl'][\CURLOPT_HTTPAUTH] = \CURLAUTH_DIGEST;
+ $options['curl'][\CURLOPT_USERPWD] = "{$value[0]}:{$value[1]}";
+ break;
+ case 'ntlm':
+ $options['curl'][\CURLOPT_HTTPAUTH] = \CURLAUTH_NTLM;
+ $options['curl'][\CURLOPT_USERPWD] = "{$value[0]}:{$value[1]}";
+ break;
+ }
+ }
+ if (isset($options['query'])) {
+ $value = $options['query'];
+ if (\is_array($value)) {
+ $value = \http_build_query($value, '', '&', \PHP_QUERY_RFC3986);
+ }
+ if (!\is_string($value)) {
+ throw new InvalidArgumentException('query must be a string or array');
+ }
+ $modify['query'] = $value;
+ unset($options['query']);
+ }
+ // Ensure that sink is not an invalid value.
+ if (isset($options['sink'])) {
+ // TODO: Add more sink validation?
+ if (\is_bool($options['sink'])) {
+ throw new InvalidArgumentException('sink must not be a boolean');
+ }
+ }
+ if (isset($options['version'])) {
+ $modify['version'] = $options['version'];
+ }
+ $request = Psr7\Utils::modifyRequest($request, $modify);
+ if ($request->getBody() instanceof Psr7\MultipartStream) {
+ // Use a multipart/form-data POST if a Content-Type is not set.
+ // Ensure that we don't have the header in different case and set the new value.
+ $options['_conditional'] = Psr7\Utils::caselessRemove(['Content-Type'], $options['_conditional']);
+ $options['_conditional']['Content-Type'] = 'multipart/form-data; boundary=' . $request->getBody()->getBoundary();
+ }
+ // Merge in conditional headers if they are not present.
+ if (isset($options['_conditional'])) {
+ // Build up the changes so it's in a single clone of the message.
+ $modify = [];
+ foreach ($options['_conditional'] as $k => $v) {
+ if (!$request->hasHeader($k)) {
+ $modify['set_headers'][$k] = $v;
+ }
+ }
+ $request = Psr7\Utils::modifyRequest($request, $modify);
+ // Don't pass this internal value along to middleware/handlers.
+ unset($options['_conditional']);
+ }
+ return $request;
+ }
+ /**
+ * Return an InvalidArgumentException with pre-set message.
+ */
+ private function invalidBody() : InvalidArgumentException
+ {
+ return new InvalidArgumentException('Passing in the "body" request ' . 'option as an array to send a request is not supported. ' . 'Please use the "form_params" request option to send a ' . 'application/x-www-form-urlencoded request, or the "multipart" ' . 'request option to send a multipart/form-data request.');
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/ClientInterface.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/ClientInterface.php
new file mode 100755
index 00000000..34204087
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/ClientInterface.php
@@ -0,0 +1,78 @@
+request('GET', $uri, $options);
+ }
+ /**
+ * Create and send an HTTP HEAD request.
+ *
+ * Use an absolute path to override the base path of the client, or a
+ * relative path to append to the base path of the client. The URL can
+ * contain the query string as well.
+ *
+ * @param string|UriInterface $uri URI object or string.
+ * @param array $options Request options to apply.
+ *
+ * @throws GuzzleException
+ */
+ public function head($uri, array $options = []) : ResponseInterface
+ {
+ return $this->request('HEAD', $uri, $options);
+ }
+ /**
+ * Create and send an HTTP PUT request.
+ *
+ * Use an absolute path to override the base path of the client, or a
+ * relative path to append to the base path of the client. The URL can
+ * contain the query string as well.
+ *
+ * @param string|UriInterface $uri URI object or string.
+ * @param array $options Request options to apply.
+ *
+ * @throws GuzzleException
+ */
+ public function put($uri, array $options = []) : ResponseInterface
+ {
+ return $this->request('PUT', $uri, $options);
+ }
+ /**
+ * Create and send an HTTP POST request.
+ *
+ * Use an absolute path to override the base path of the client, or a
+ * relative path to append to the base path of the client. The URL can
+ * contain the query string as well.
+ *
+ * @param string|UriInterface $uri URI object or string.
+ * @param array $options Request options to apply.
+ *
+ * @throws GuzzleException
+ */
+ public function post($uri, array $options = []) : ResponseInterface
+ {
+ return $this->request('POST', $uri, $options);
+ }
+ /**
+ * Create and send an HTTP PATCH request.
+ *
+ * Use an absolute path to override the base path of the client, or a
+ * relative path to append to the base path of the client. The URL can
+ * contain the query string as well.
+ *
+ * @param string|UriInterface $uri URI object or string.
+ * @param array $options Request options to apply.
+ *
+ * @throws GuzzleException
+ */
+ public function patch($uri, array $options = []) : ResponseInterface
+ {
+ return $this->request('PATCH', $uri, $options);
+ }
+ /**
+ * Create and send an HTTP DELETE request.
+ *
+ * Use an absolute path to override the base path of the client, or a
+ * relative path to append to the base path of the client. The URL can
+ * contain the query string as well.
+ *
+ * @param string|UriInterface $uri URI object or string.
+ * @param array $options Request options to apply.
+ *
+ * @throws GuzzleException
+ */
+ public function delete($uri, array $options = []) : ResponseInterface
+ {
+ return $this->request('DELETE', $uri, $options);
+ }
+ /**
+ * Create and send an asynchronous HTTP request.
+ *
+ * Use an absolute path to override the base path of the client, or a
+ * relative path to append to the base path of the client. The URL can
+ * contain the query string as well. Use an array to provide a URL
+ * template and additional variables to use in the URL template expansion.
+ *
+ * @param string $method HTTP method
+ * @param string|UriInterface $uri URI object or string.
+ * @param array $options Request options to apply.
+ */
+ public abstract function requestAsync(string $method, $uri, array $options = []) : PromiseInterface;
+ /**
+ * Create and send an asynchronous HTTP GET request.
+ *
+ * Use an absolute path to override the base path of the client, or a
+ * relative path to append to the base path of the client. The URL can
+ * contain the query string as well. Use an array to provide a URL
+ * template and additional variables to use in the URL template expansion.
+ *
+ * @param string|UriInterface $uri URI object or string.
+ * @param array $options Request options to apply.
+ */
+ public function getAsync($uri, array $options = []) : PromiseInterface
+ {
+ return $this->requestAsync('GET', $uri, $options);
+ }
+ /**
+ * Create and send an asynchronous HTTP HEAD request.
+ *
+ * Use an absolute path to override the base path of the client, or a
+ * relative path to append to the base path of the client. The URL can
+ * contain the query string as well. Use an array to provide a URL
+ * template and additional variables to use in the URL template expansion.
+ *
+ * @param string|UriInterface $uri URI object or string.
+ * @param array $options Request options to apply.
+ */
+ public function headAsync($uri, array $options = []) : PromiseInterface
+ {
+ return $this->requestAsync('HEAD', $uri, $options);
+ }
+ /**
+ * Create and send an asynchronous HTTP PUT request.
+ *
+ * Use an absolute path to override the base path of the client, or a
+ * relative path to append to the base path of the client. The URL can
+ * contain the query string as well. Use an array to provide a URL
+ * template and additional variables to use in the URL template expansion.
+ *
+ * @param string|UriInterface $uri URI object or string.
+ * @param array $options Request options to apply.
+ */
+ public function putAsync($uri, array $options = []) : PromiseInterface
+ {
+ return $this->requestAsync('PUT', $uri, $options);
+ }
+ /**
+ * Create and send an asynchronous HTTP POST request.
+ *
+ * Use an absolute path to override the base path of the client, or a
+ * relative path to append to the base path of the client. The URL can
+ * contain the query string as well. Use an array to provide a URL
+ * template and additional variables to use in the URL template expansion.
+ *
+ * @param string|UriInterface $uri URI object or string.
+ * @param array $options Request options to apply.
+ */
+ public function postAsync($uri, array $options = []) : PromiseInterface
+ {
+ return $this->requestAsync('POST', $uri, $options);
+ }
+ /**
+ * Create and send an asynchronous HTTP PATCH request.
+ *
+ * Use an absolute path to override the base path of the client, or a
+ * relative path to append to the base path of the client. The URL can
+ * contain the query string as well. Use an array to provide a URL
+ * template and additional variables to use in the URL template expansion.
+ *
+ * @param string|UriInterface $uri URI object or string.
+ * @param array $options Request options to apply.
+ */
+ public function patchAsync($uri, array $options = []) : PromiseInterface
+ {
+ return $this->requestAsync('PATCH', $uri, $options);
+ }
+ /**
+ * Create and send an asynchronous HTTP DELETE request.
+ *
+ * Use an absolute path to override the base path of the client, or a
+ * relative path to append to the base path of the client. The URL can
+ * contain the query string as well. Use an array to provide a URL
+ * template and additional variables to use in the URL template expansion.
+ *
+ * @param string|UriInterface $uri URI object or string.
+ * @param array $options Request options to apply.
+ */
+ public function deleteAsync($uri, array $options = []) : PromiseInterface
+ {
+ return $this->requestAsync('DELETE', $uri, $options);
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/Cookie/CookieJar.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/Cookie/CookieJar.php
new file mode 100755
index 00000000..2006fe23
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/Cookie/CookieJar.php
@@ -0,0 +1,240 @@
+strictMode = $strictMode;
+ foreach ($cookieArray as $cookie) {
+ if (!$cookie instanceof SetCookie) {
+ $cookie = new SetCookie($cookie);
+ }
+ $this->setCookie($cookie);
+ }
+ }
+ /**
+ * Create a new Cookie jar from an associative array and domain.
+ *
+ * @param array $cookies Cookies to create the jar from
+ * @param string $domain Domain to set the cookies to
+ */
+ public static function fromArray(array $cookies, string $domain) : self
+ {
+ $cookieJar = new self();
+ foreach ($cookies as $name => $value) {
+ $cookieJar->setCookie(new SetCookie(['Domain' => $domain, 'Name' => $name, 'Value' => $value, 'Discard' => \true]));
+ }
+ return $cookieJar;
+ }
+ /**
+ * Evaluate if this cookie should be persisted to storage
+ * that survives between requests.
+ *
+ * @param SetCookie $cookie Being evaluated.
+ * @param bool $allowSessionCookies If we should persist session cookies
+ */
+ public static function shouldPersist(SetCookie $cookie, bool $allowSessionCookies = \false) : bool
+ {
+ if ($cookie->getExpires() || $allowSessionCookies) {
+ if (!$cookie->getDiscard()) {
+ return \true;
+ }
+ }
+ return \false;
+ }
+ /**
+ * Finds and returns the cookie based on the name
+ *
+ * @param string $name cookie name to search for
+ *
+ * @return SetCookie|null cookie that was found or null if not found
+ */
+ public function getCookieByName(string $name) : ?SetCookie
+ {
+ foreach ($this->cookies as $cookie) {
+ if ($cookie->getName() !== null && \strcasecmp($cookie->getName(), $name) === 0) {
+ return $cookie;
+ }
+ }
+ return null;
+ }
+ public function toArray() : array
+ {
+ return \array_map(static function (SetCookie $cookie) : array {
+ return $cookie->toArray();
+ }, $this->getIterator()->getArrayCopy());
+ }
+ public function clear(?string $domain = null, ?string $path = null, ?string $name = null) : void
+ {
+ if (!$domain) {
+ $this->cookies = [];
+ return;
+ } elseif (!$path) {
+ $this->cookies = \array_filter($this->cookies, static function (SetCookie $cookie) use($domain) : bool {
+ return !$cookie->matchesDomain($domain);
+ });
+ } elseif (!$name) {
+ $this->cookies = \array_filter($this->cookies, static function (SetCookie $cookie) use($path, $domain) : bool {
+ return !($cookie->matchesPath($path) && $cookie->matchesDomain($domain));
+ });
+ } else {
+ $this->cookies = \array_filter($this->cookies, static function (SetCookie $cookie) use($path, $domain, $name) {
+ return !($cookie->getName() == $name && $cookie->matchesPath($path) && $cookie->matchesDomain($domain));
+ });
+ }
+ }
+ public function clearSessionCookies() : void
+ {
+ $this->cookies = \array_filter($this->cookies, static function (SetCookie $cookie) : bool {
+ return !$cookie->getDiscard() && $cookie->getExpires();
+ });
+ }
+ public function setCookie(SetCookie $cookie) : bool
+ {
+ // If the name string is empty (but not 0), ignore the set-cookie
+ // string entirely.
+ $name = $cookie->getName();
+ if (!$name && $name !== '0') {
+ return \false;
+ }
+ // Only allow cookies with set and valid domain, name, value
+ $result = $cookie->validate();
+ if ($result !== \true) {
+ if ($this->strictMode) {
+ throw new \RuntimeException('Invalid cookie: ' . $result);
+ }
+ $this->removeCookieIfEmpty($cookie);
+ return \false;
+ }
+ // Resolve conflicts with previously set cookies
+ foreach ($this->cookies as $i => $c) {
+ // Two cookies are identical, when their path, and domain are
+ // identical.
+ if ($c->getPath() != $cookie->getPath() || $c->getDomain() != $cookie->getDomain() || $c->getName() != $cookie->getName()) {
+ continue;
+ }
+ // The previously set cookie is a discard cookie and this one is
+ // not so allow the new cookie to be set
+ if (!$cookie->getDiscard() && $c->getDiscard()) {
+ unset($this->cookies[$i]);
+ continue;
+ }
+ // If the new cookie's expiration is further into the future, then
+ // replace the old cookie
+ if ($cookie->getExpires() > $c->getExpires()) {
+ unset($this->cookies[$i]);
+ continue;
+ }
+ // If the value has changed, we better change it
+ if ($cookie->getValue() !== $c->getValue()) {
+ unset($this->cookies[$i]);
+ continue;
+ }
+ // The cookie exists, so no need to continue
+ return \false;
+ }
+ $this->cookies[] = $cookie;
+ return \true;
+ }
+ public function count() : int
+ {
+ return \count($this->cookies);
+ }
+ /**
+ * @return \ArrayIterator
+ */
+ public function getIterator() : \ArrayIterator
+ {
+ return new \ArrayIterator(\array_values($this->cookies));
+ }
+ public function extractCookies(RequestInterface $request, ResponseInterface $response) : void
+ {
+ if ($cookieHeader = $response->getHeader('Set-Cookie')) {
+ foreach ($cookieHeader as $cookie) {
+ $sc = SetCookie::fromString($cookie);
+ if (!$sc->getDomain()) {
+ $sc->setDomain($request->getUri()->getHost());
+ }
+ if (0 !== \strpos($sc->getPath(), '/')) {
+ $sc->setPath($this->getCookiePathFromRequest($request));
+ }
+ if (!$sc->matchesDomain($request->getUri()->getHost())) {
+ continue;
+ }
+ // Note: At this point `$sc->getDomain()` being a public suffix should
+ // be rejected, but we don't want to pull in the full PSL dependency.
+ $this->setCookie($sc);
+ }
+ }
+ }
+ /**
+ * Computes cookie path following RFC 6265 section 5.1.4
+ *
+ * @see https://datatracker.ietf.org/doc/html/rfc6265#section-5.1.4
+ */
+ private function getCookiePathFromRequest(RequestInterface $request) : string
+ {
+ $uriPath = $request->getUri()->getPath();
+ if ('' === $uriPath) {
+ return '/';
+ }
+ if (0 !== \strpos($uriPath, '/')) {
+ return '/';
+ }
+ if ('/' === $uriPath) {
+ return '/';
+ }
+ $lastSlashPos = \strrpos($uriPath, '/');
+ if (0 === $lastSlashPos || \false === $lastSlashPos) {
+ return '/';
+ }
+ return \substr($uriPath, 0, $lastSlashPos);
+ }
+ public function withCookieHeader(RequestInterface $request) : RequestInterface
+ {
+ $values = [];
+ $uri = $request->getUri();
+ $scheme = $uri->getScheme();
+ $host = $uri->getHost();
+ $path = $uri->getPath() ?: '/';
+ foreach ($this->cookies as $cookie) {
+ if ($cookie->matchesPath($path) && $cookie->matchesDomain($host) && !$cookie->isExpired() && (!$cookie->getSecure() || $scheme === 'https')) {
+ $values[] = $cookie->getName() . '=' . $cookie->getValue();
+ }
+ }
+ return $values ? $request->withHeader('Cookie', \implode('; ', $values)) : $request;
+ }
+ /**
+ * If a cookie already exists and the server asks to set it again with a
+ * null value, the cookie must be deleted.
+ */
+ private function removeCookieIfEmpty(SetCookie $cookie) : void
+ {
+ $cookieValue = $cookie->getValue();
+ if ($cookieValue === null || $cookieValue === '') {
+ $this->clear($cookie->getDomain(), $cookie->getPath(), $cookie->getName());
+ }
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php
new file mode 100755
index 00000000..21343bf3
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php
@@ -0,0 +1,74 @@
+
+ */
+interface CookieJarInterface extends \Countable, \IteratorAggregate
+{
+ /**
+ * Create a request with added cookie headers.
+ *
+ * If no matching cookies are found in the cookie jar, then no Cookie
+ * header is added to the request and the same request is returned.
+ *
+ * @param RequestInterface $request Request object to modify.
+ *
+ * @return RequestInterface returns the modified request.
+ */
+ public function withCookieHeader(RequestInterface $request) : RequestInterface;
+ /**
+ * Extract cookies from an HTTP response and store them in the CookieJar.
+ *
+ * @param RequestInterface $request Request that was sent
+ * @param ResponseInterface $response Response that was received
+ */
+ public function extractCookies(RequestInterface $request, ResponseInterface $response) : void;
+ /**
+ * Sets a cookie in the cookie jar.
+ *
+ * @param SetCookie $cookie Cookie to set.
+ *
+ * @return bool Returns true on success or false on failure
+ */
+ public function setCookie(SetCookie $cookie) : bool;
+ /**
+ * Remove cookies currently held in the cookie jar.
+ *
+ * Invoking this method without arguments will empty the whole cookie jar.
+ * If given a $domain argument only cookies belonging to that domain will
+ * be removed. If given a $domain and $path argument, cookies belonging to
+ * the specified path within that domain are removed. If given all three
+ * arguments, then the cookie with the specified name, path and domain is
+ * removed.
+ *
+ * @param string|null $domain Clears cookies matching a domain
+ * @param string|null $path Clears cookies matching a domain and path
+ * @param string|null $name Clears cookies matching a domain, path, and name
+ */
+ public function clear(?string $domain = null, ?string $path = null, ?string $name = null) : void;
+ /**
+ * Discard all sessions cookies.
+ *
+ * Removes cookies that don't have an expire field or a have a discard
+ * field set to true. To be called when the user agent shuts down according
+ * to RFC 2965.
+ */
+ public function clearSessionCookies() : void;
+ /**
+ * Converts the cookie jar to an array.
+ */
+ public function toArray() : array;
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/Cookie/FileCookieJar.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/Cookie/FileCookieJar.php
new file mode 100755
index 00000000..8bf65d30
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/Cookie/FileCookieJar.php
@@ -0,0 +1,92 @@
+filename = $cookieFile;
+ $this->storeSessionCookies = $storeSessionCookies;
+ if (\file_exists($cookieFile)) {
+ $this->load($cookieFile);
+ }
+ }
+ /**
+ * Saves the file when shutting down
+ */
+ public function __destruct()
+ {
+ $this->save($this->filename);
+ }
+ /**
+ * Saves the cookies to a file.
+ *
+ * @param string $filename File to save
+ *
+ * @throws \RuntimeException if the file cannot be found or created
+ */
+ public function save(string $filename) : void
+ {
+ $json = [];
+ /** @var SetCookie $cookie */
+ foreach ($this as $cookie) {
+ if (CookieJar::shouldPersist($cookie, $this->storeSessionCookies)) {
+ $json[] = $cookie->toArray();
+ }
+ }
+ $jsonStr = Utils::jsonEncode($json);
+ if (\false === \file_put_contents($filename, $jsonStr, \LOCK_EX)) {
+ throw new \RuntimeException("Unable to save file {$filename}");
+ }
+ }
+ /**
+ * Load cookies from a JSON formatted file.
+ *
+ * Old cookies are kept unless overwritten by newly loaded ones.
+ *
+ * @param string $filename Cookie file to load.
+ *
+ * @throws \RuntimeException if the file cannot be loaded.
+ */
+ public function load(string $filename) : void
+ {
+ $json = \file_get_contents($filename);
+ if (\false === $json) {
+ throw new \RuntimeException("Unable to load file {$filename}");
+ }
+ if ($json === '') {
+ return;
+ }
+ $data = Utils::jsonDecode($json, \true);
+ if (\is_array($data)) {
+ foreach ($data as $cookie) {
+ $this->setCookie(new SetCookie($cookie));
+ }
+ } elseif (\is_scalar($data) && !empty($data)) {
+ throw new \RuntimeException("Invalid cookie file: {$filename}");
+ }
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/Cookie/SessionCookieJar.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/Cookie/SessionCookieJar.php
new file mode 100755
index 00000000..ea6dc344
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/Cookie/SessionCookieJar.php
@@ -0,0 +1,71 @@
+sessionKey = $sessionKey;
+ $this->storeSessionCookies = $storeSessionCookies;
+ $this->load();
+ }
+ /**
+ * Saves cookies to session when shutting down
+ */
+ public function __destruct()
+ {
+ $this->save();
+ }
+ /**
+ * Save cookies to the client session
+ */
+ public function save() : void
+ {
+ $json = [];
+ /** @var SetCookie $cookie */
+ foreach ($this as $cookie) {
+ if (CookieJar::shouldPersist($cookie, $this->storeSessionCookies)) {
+ $json[] = $cookie->toArray();
+ }
+ }
+ $_SESSION[$this->sessionKey] = \json_encode($json);
+ }
+ /**
+ * Load the contents of the client session into the data array
+ */
+ protected function load() : void
+ {
+ if (!isset($_SESSION[$this->sessionKey])) {
+ return;
+ }
+ $data = \json_decode($_SESSION[$this->sessionKey], \true);
+ if (\is_array($data)) {
+ foreach ($data as $cookie) {
+ $this->setCookie(new SetCookie($cookie));
+ }
+ } elseif (\strlen($data)) {
+ throw new \RuntimeException('Invalid cookie data');
+ }
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/Cookie/SetCookie.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/Cookie/SetCookie.php
new file mode 100755
index 00000000..955dc730
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/Cookie/SetCookie.php
@@ -0,0 +1,411 @@
+ null, 'Value' => null, 'Domain' => null, 'Path' => '/', 'Max-Age' => null, 'Expires' => null, 'Secure' => \false, 'Discard' => \false, 'HttpOnly' => \false];
+ /**
+ * @var array Cookie data
+ */
+ private $data;
+ /**
+ * Create a new SetCookie object from a string.
+ *
+ * @param string $cookie Set-Cookie header string
+ */
+ public static function fromString(string $cookie) : self
+ {
+ // Create the default return array
+ $data = self::$defaults;
+ // Explode the cookie string using a series of semicolons
+ $pieces = \array_filter(\array_map('trim', \explode(';', $cookie)));
+ // The name of the cookie (first kvp) must exist and include an equal sign.
+ if (!isset($pieces[0]) || \strpos($pieces[0], '=') === \false) {
+ return new self($data);
+ }
+ // Add the cookie pieces into the parsed data array
+ foreach ($pieces as $part) {
+ $cookieParts = \explode('=', $part, 2);
+ $key = \trim($cookieParts[0]);
+ $value = isset($cookieParts[1]) ? \trim($cookieParts[1], " \n\r\t\x00\v") : \true;
+ // Only check for non-cookies when cookies have been found
+ if (!isset($data['Name'])) {
+ $data['Name'] = $key;
+ $data['Value'] = $value;
+ } else {
+ foreach (\array_keys(self::$defaults) as $search) {
+ if (!\strcasecmp($search, $key)) {
+ if ($search === 'Max-Age') {
+ if (\is_numeric($value)) {
+ $data[$search] = (int) $value;
+ }
+ } elseif ($search === 'Secure' || $search === 'Discard' || $search === 'HttpOnly') {
+ if ($value) {
+ $data[$search] = \true;
+ }
+ } else {
+ $data[$search] = $value;
+ }
+ continue 2;
+ }
+ }
+ $data[$key] = $value;
+ }
+ }
+ return new self($data);
+ }
+ /**
+ * @param array $data Array of cookie data provided by a Cookie parser
+ */
+ public function __construct(array $data = [])
+ {
+ $this->data = self::$defaults;
+ if (isset($data['Name'])) {
+ $this->setName($data['Name']);
+ }
+ if (isset($data['Value'])) {
+ $this->setValue($data['Value']);
+ }
+ if (isset($data['Domain'])) {
+ $this->setDomain($data['Domain']);
+ }
+ if (isset($data['Path'])) {
+ $this->setPath($data['Path']);
+ }
+ if (isset($data['Max-Age'])) {
+ $this->setMaxAge($data['Max-Age']);
+ }
+ if (isset($data['Expires'])) {
+ $this->setExpires($data['Expires']);
+ }
+ if (isset($data['Secure'])) {
+ $this->setSecure($data['Secure']);
+ }
+ if (isset($data['Discard'])) {
+ $this->setDiscard($data['Discard']);
+ }
+ if (isset($data['HttpOnly'])) {
+ $this->setHttpOnly($data['HttpOnly']);
+ }
+ // Set the remaining values that don't have extra validation logic
+ foreach (\array_diff(\array_keys($data), \array_keys(self::$defaults)) as $key) {
+ $this->data[$key] = $data[$key];
+ }
+ // Extract the Expires value and turn it into a UNIX timestamp if needed
+ if (!$this->getExpires() && $this->getMaxAge()) {
+ // Calculate the Expires date
+ $this->setExpires(\time() + $this->getMaxAge());
+ } elseif (null !== ($expires = $this->getExpires()) && !\is_numeric($expires)) {
+ $this->setExpires($expires);
+ }
+ }
+ public function __toString()
+ {
+ $str = $this->data['Name'] . '=' . ($this->data['Value'] ?? '') . '; ';
+ foreach ($this->data as $k => $v) {
+ if ($k !== 'Name' && $k !== 'Value' && $v !== null && $v !== \false) {
+ if ($k === 'Expires') {
+ $str .= 'Expires=' . \gmdate('D, d M Y H:i:s \\G\\M\\T', $v) . '; ';
+ } else {
+ $str .= ($v === \true ? $k : "{$k}={$v}") . '; ';
+ }
+ }
+ }
+ return \rtrim($str, '; ');
+ }
+ public function toArray() : array
+ {
+ return $this->data;
+ }
+ /**
+ * Get the cookie name.
+ *
+ * @return string
+ */
+ public function getName()
+ {
+ return $this->data['Name'];
+ }
+ /**
+ * Set the cookie name.
+ *
+ * @param string $name Cookie name
+ */
+ public function setName($name) : void
+ {
+ if (!\is_string($name)) {
+ trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing a string to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__);
+ }
+ $this->data['Name'] = (string) $name;
+ }
+ /**
+ * Get the cookie value.
+ *
+ * @return string|null
+ */
+ public function getValue()
+ {
+ return $this->data['Value'];
+ }
+ /**
+ * Set the cookie value.
+ *
+ * @param string $value Cookie value
+ */
+ public function setValue($value) : void
+ {
+ if (!\is_string($value)) {
+ trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing a string to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__);
+ }
+ $this->data['Value'] = (string) $value;
+ }
+ /**
+ * Get the domain.
+ *
+ * @return string|null
+ */
+ public function getDomain()
+ {
+ return $this->data['Domain'];
+ }
+ /**
+ * Set the domain of the cookie.
+ *
+ * @param string|null $domain
+ */
+ public function setDomain($domain) : void
+ {
+ if (!\is_string($domain) && null !== $domain) {
+ trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing a string or null to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__);
+ }
+ $this->data['Domain'] = null === $domain ? null : (string) $domain;
+ }
+ /**
+ * Get the path.
+ *
+ * @return string
+ */
+ public function getPath()
+ {
+ return $this->data['Path'];
+ }
+ /**
+ * Set the path of the cookie.
+ *
+ * @param string $path Path of the cookie
+ */
+ public function setPath($path) : void
+ {
+ if (!\is_string($path)) {
+ trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing a string to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__);
+ }
+ $this->data['Path'] = (string) $path;
+ }
+ /**
+ * Maximum lifetime of the cookie in seconds.
+ *
+ * @return int|null
+ */
+ public function getMaxAge()
+ {
+ return null === $this->data['Max-Age'] ? null : (int) $this->data['Max-Age'];
+ }
+ /**
+ * Set the max-age of the cookie.
+ *
+ * @param int|null $maxAge Max age of the cookie in seconds
+ */
+ public function setMaxAge($maxAge) : void
+ {
+ if (!\is_int($maxAge) && null !== $maxAge) {
+ trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing an int or null to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__);
+ }
+ $this->data['Max-Age'] = $maxAge === null ? null : (int) $maxAge;
+ }
+ /**
+ * The UNIX timestamp when the cookie Expires.
+ *
+ * @return string|int|null
+ */
+ public function getExpires()
+ {
+ return $this->data['Expires'];
+ }
+ /**
+ * Set the unix timestamp for which the cookie will expire.
+ *
+ * @param int|string|null $timestamp Unix timestamp or any English textual datetime description.
+ */
+ public function setExpires($timestamp) : void
+ {
+ if (!\is_int($timestamp) && !\is_string($timestamp) && null !== $timestamp) {
+ trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing an int, string or null to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__);
+ }
+ $this->data['Expires'] = null === $timestamp ? null : (\is_numeric($timestamp) ? (int) $timestamp : \strtotime((string) $timestamp));
+ }
+ /**
+ * Get whether or not this is a secure cookie.
+ *
+ * @return bool
+ */
+ public function getSecure()
+ {
+ return $this->data['Secure'];
+ }
+ /**
+ * Set whether or not the cookie is secure.
+ *
+ * @param bool $secure Set to true or false if secure
+ */
+ public function setSecure($secure) : void
+ {
+ if (!\is_bool($secure)) {
+ trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing a bool to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__);
+ }
+ $this->data['Secure'] = (bool) $secure;
+ }
+ /**
+ * Get whether or not this is a session cookie.
+ *
+ * @return bool|null
+ */
+ public function getDiscard()
+ {
+ return $this->data['Discard'];
+ }
+ /**
+ * Set whether or not this is a session cookie.
+ *
+ * @param bool $discard Set to true or false if this is a session cookie
+ */
+ public function setDiscard($discard) : void
+ {
+ if (!\is_bool($discard)) {
+ trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing a bool to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__);
+ }
+ $this->data['Discard'] = (bool) $discard;
+ }
+ /**
+ * Get whether or not this is an HTTP only cookie.
+ *
+ * @return bool
+ */
+ public function getHttpOnly()
+ {
+ return $this->data['HttpOnly'];
+ }
+ /**
+ * Set whether or not this is an HTTP only cookie.
+ *
+ * @param bool $httpOnly Set to true or false if this is HTTP only
+ */
+ public function setHttpOnly($httpOnly) : void
+ {
+ if (!\is_bool($httpOnly)) {
+ trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing a bool to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__);
+ }
+ $this->data['HttpOnly'] = (bool) $httpOnly;
+ }
+ /**
+ * Check if the cookie matches a path value.
+ *
+ * A request-path path-matches a given cookie-path if at least one of
+ * the following conditions holds:
+ *
+ * - The cookie-path and the request-path are identical.
+ * - The cookie-path is a prefix of the request-path, and the last
+ * character of the cookie-path is %x2F ("/").
+ * - The cookie-path is a prefix of the request-path, and the first
+ * character of the request-path that is not included in the cookie-
+ * path is a %x2F ("/") character.
+ *
+ * @param string $requestPath Path to check against
+ */
+ public function matchesPath(string $requestPath) : bool
+ {
+ $cookiePath = $this->getPath();
+ // Match on exact matches or when path is the default empty "/"
+ if ($cookiePath === '/' || $cookiePath == $requestPath) {
+ return \true;
+ }
+ // Ensure that the cookie-path is a prefix of the request path.
+ if (0 !== \strpos($requestPath, $cookiePath)) {
+ return \false;
+ }
+ // Match if the last character of the cookie-path is "/"
+ if (\substr($cookiePath, -1, 1) === '/') {
+ return \true;
+ }
+ // Match if the first character not included in cookie path is "/"
+ return \substr($requestPath, \strlen($cookiePath), 1) === '/';
+ }
+ /**
+ * Check if the cookie matches a domain value.
+ *
+ * @param string $domain Domain to check against
+ */
+ public function matchesDomain(string $domain) : bool
+ {
+ $cookieDomain = $this->getDomain();
+ if (null === $cookieDomain) {
+ return \true;
+ }
+ // Remove the leading '.' as per spec in RFC 6265.
+ // https://datatracker.ietf.org/doc/html/rfc6265#section-5.2.3
+ $cookieDomain = \ltrim(\strtolower($cookieDomain), '.');
+ $domain = \strtolower($domain);
+ // Domain not set or exact match.
+ if ('' === $cookieDomain || $domain === $cookieDomain) {
+ return \true;
+ }
+ // Matching the subdomain according to RFC 6265.
+ // https://datatracker.ietf.org/doc/html/rfc6265#section-5.1.3
+ if (\filter_var($domain, \FILTER_VALIDATE_IP)) {
+ return \false;
+ }
+ return (bool) \preg_match('/\\.' . \preg_quote($cookieDomain, '/') . '$/', $domain);
+ }
+ /**
+ * Check if the cookie is expired.
+ */
+ public function isExpired() : bool
+ {
+ return $this->getExpires() !== null && \time() > $this->getExpires();
+ }
+ /**
+ * Check if the cookie is valid according to RFC 6265.
+ *
+ * @return bool|string Returns true if valid or an error message if invalid
+ */
+ public function validate()
+ {
+ $name = $this->getName();
+ if ($name === '') {
+ return 'The cookie name must not be empty';
+ }
+ // Check if any of the invalid characters are present in the cookie name
+ if (\preg_match('/[\\x00-\\x20\\x22\\x28-\\x29\\x2c\\x2f\\x3a-\\x40\\x5c\\x7b\\x7d\\x7f]/', $name)) {
+ return 'Cookie name must not contain invalid characters: ASCII ' . 'Control characters (0-31;127), space, tab and the ' . 'following characters: ()<>@,;:\\"/?={}';
+ }
+ // Value must not be null. 0 and empty string are valid. Empty strings
+ // are technically against RFC 6265, but known to happen in the wild.
+ $value = $this->getValue();
+ if ($value === null) {
+ return 'The cookie value must not be empty';
+ }
+ // Domains must not be empty, but can be 0. "0" is not a valid internet
+ // domain, but may be used as server name in a private network.
+ $domain = $this->getDomain();
+ if ($domain === null || $domain === '') {
+ return 'The cookie domain must not be empty';
+ }
+ return \true;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/Exception/BadResponseException.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/Exception/BadResponseException.php
new file mode 100755
index 00000000..89617dde
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/Exception/BadResponseException.php
@@ -0,0 +1,31 @@
+request = $request;
+ $this->handlerContext = $handlerContext;
+ }
+ /**
+ * Get the request that caused the exception
+ */
+ public function getRequest() : RequestInterface
+ {
+ return $this->request;
+ }
+ /**
+ * Get contextual information about the error from the underlying handler.
+ *
+ * The contents of this array will vary depending on which handler you are
+ * using. It may also be just an empty array. Relying on this data will
+ * couple you to a specific handler, but can give more debug information
+ * when needed.
+ */
+ public function getHandlerContext() : array
+ {
+ return $this->handlerContext;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/Exception/GuzzleException.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/Exception/GuzzleException.php
new file mode 100755
index 00000000..ad5a9a54
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/Exception/GuzzleException.php
@@ -0,0 +1,8 @@
+getStatusCode() : 0;
+ parent::__construct($message, $code, $previous);
+ $this->request = $request;
+ $this->response = $response;
+ $this->handlerContext = $handlerContext;
+ }
+ /**
+ * Wrap non-RequestExceptions with a RequestException
+ */
+ public static function wrapException(RequestInterface $request, \Throwable $e) : RequestException
+ {
+ return $e instanceof RequestException ? $e : new RequestException($e->getMessage(), $request, null, $e);
+ }
+ /**
+ * Factory method to create a new exception with a normalized error message
+ *
+ * @param RequestInterface $request Request sent
+ * @param ResponseInterface $response Response received
+ * @param \Throwable|null $previous Previous exception
+ * @param array $handlerContext Optional handler context
+ * @param BodySummarizerInterface|null $bodySummarizer Optional body summarizer
+ */
+ public static function create(RequestInterface $request, ?ResponseInterface $response = null, ?\Throwable $previous = null, array $handlerContext = [], ?BodySummarizerInterface $bodySummarizer = null) : self
+ {
+ if (!$response) {
+ return new self('Error completing request', $request, null, $previous, $handlerContext);
+ }
+ $level = (int) \floor($response->getStatusCode() / 100);
+ if ($level === 4) {
+ $label = 'Client error';
+ $className = ClientException::class;
+ } elseif ($level === 5) {
+ $label = 'Server error';
+ $className = ServerException::class;
+ } else {
+ $label = 'Unsuccessful request';
+ $className = __CLASS__;
+ }
+ $uri = \WPMailSMTP\Vendor\GuzzleHttp\Psr7\Utils::redactUserInfo($request->getUri());
+ // Client Error: `GET /` resulted in a `404 Not Found` response:
+ // ... (truncated)
+ $message = \sprintf('%s: `%s %s` resulted in a `%s %s` response', $label, $request->getMethod(), $uri->__toString(), $response->getStatusCode(), $response->getReasonPhrase());
+ $summary = ($bodySummarizer ?? new BodySummarizer())->summarize($response);
+ if ($summary !== null) {
+ $message .= ":\n{$summary}\n";
+ }
+ return new $className($message, $request, $response, $previous, $handlerContext);
+ }
+ /**
+ * Get the request that caused the exception
+ */
+ public function getRequest() : RequestInterface
+ {
+ return $this->request;
+ }
+ /**
+ * Get the associated response
+ */
+ public function getResponse() : ?ResponseInterface
+ {
+ return $this->response;
+ }
+ /**
+ * Check if a response was received
+ */
+ public function hasResponse() : bool
+ {
+ return $this->response !== null;
+ }
+ /**
+ * Get contextual information about the error from the underlying handler.
+ *
+ * The contents of this array will vary depending on which handler you are
+ * using. It may also be just an empty array. Relying on this data will
+ * couple you to a specific handler, but can give more debug information
+ * when needed.
+ */
+ public function getHandlerContext() : array
+ {
+ return $this->handlerContext;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/Exception/ServerException.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/Exception/ServerException.php
new file mode 100755
index 00000000..c00261f4
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/Exception/ServerException.php
@@ -0,0 +1,10 @@
+maxHandles = $maxHandles;
+ }
+ public function create(RequestInterface $request, array $options) : EasyHandle
+ {
+ $protocolVersion = $request->getProtocolVersion();
+ if ('2' === $protocolVersion || '2.0' === $protocolVersion) {
+ if (!self::supportsHttp2()) {
+ throw new ConnectException('HTTP/2 is supported by the cURL handler, however libcurl is built without HTTP/2 support.', $request);
+ }
+ } elseif ('1.0' !== $protocolVersion && '1.1' !== $protocolVersion) {
+ throw new ConnectException(\sprintf('HTTP/%s is not supported by the cURL handler.', $protocolVersion), $request);
+ }
+ if (isset($options['curl']['body_as_string'])) {
+ $options['_body_as_string'] = $options['curl']['body_as_string'];
+ unset($options['curl']['body_as_string']);
+ }
+ $easy = new EasyHandle();
+ $easy->request = $request;
+ $easy->options = $options;
+ $conf = $this->getDefaultConf($easy);
+ $this->applyMethod($easy, $conf);
+ $this->applyHandlerOptions($easy, $conf);
+ $this->applyHeaders($easy, $conf);
+ unset($conf['_headers']);
+ // Add handler options from the request configuration options
+ if (isset($options['curl'])) {
+ $conf = \array_replace($conf, $options['curl']);
+ }
+ $conf[\CURLOPT_HEADERFUNCTION] = $this->createHeaderFn($easy);
+ $easy->handle = $this->handles ? \array_pop($this->handles) : \curl_init();
+ \curl_setopt_array($easy->handle, $conf);
+ return $easy;
+ }
+ private static function supportsHttp2() : bool
+ {
+ static $supportsHttp2 = null;
+ if (null === $supportsHttp2) {
+ $supportsHttp2 = self::supportsTls12() && \defined('CURL_VERSION_HTTP2') && \CURL_VERSION_HTTP2 & \curl_version()['features'];
+ }
+ return $supportsHttp2;
+ }
+ private static function supportsTls12() : bool
+ {
+ static $supportsTls12 = null;
+ if (null === $supportsTls12) {
+ $supportsTls12 = \CURL_SSLVERSION_TLSv1_2 & \curl_version()['features'];
+ }
+ return $supportsTls12;
+ }
+ private static function supportsTls13() : bool
+ {
+ static $supportsTls13 = null;
+ if (null === $supportsTls13) {
+ $supportsTls13 = \defined('CURL_SSLVERSION_TLSv1_3') && \CURL_SSLVERSION_TLSv1_3 & \curl_version()['features'];
+ }
+ return $supportsTls13;
+ }
+ public function release(EasyHandle $easy) : void
+ {
+ $resource = $easy->handle;
+ unset($easy->handle);
+ if (\count($this->handles) >= $this->maxHandles) {
+ if (\PHP_VERSION_ID < 80000) {
+ \curl_close($resource);
+ }
+ } else {
+ // Remove all callback functions as they can hold onto references
+ // and are not cleaned up by curl_reset. Using curl_setopt_array
+ // does not work for some reason, so removing each one
+ // individually.
+ \curl_setopt($resource, \CURLOPT_HEADERFUNCTION, null);
+ \curl_setopt($resource, \CURLOPT_READFUNCTION, null);
+ \curl_setopt($resource, \CURLOPT_WRITEFUNCTION, null);
+ \curl_setopt($resource, \CURLOPT_PROGRESSFUNCTION, null);
+ \curl_reset($resource);
+ $this->handles[] = $resource;
+ }
+ }
+ /**
+ * Completes a cURL transaction, either returning a response promise or a
+ * rejected promise.
+ *
+ * @param callable(RequestInterface, array): PromiseInterface $handler
+ * @param CurlFactoryInterface $factory Dictates how the handle is released
+ */
+ public static function finish(callable $handler, EasyHandle $easy, CurlFactoryInterface $factory) : PromiseInterface
+ {
+ if (isset($easy->options['on_stats'])) {
+ self::invokeStats($easy);
+ }
+ if (!$easy->response || $easy->errno) {
+ return self::finishError($handler, $easy, $factory);
+ }
+ // Return the response if it is present and there is no error.
+ $factory->release($easy);
+ // Rewind the body of the response if possible.
+ $body = $easy->response->getBody();
+ if ($body->isSeekable()) {
+ $body->rewind();
+ }
+ return new FulfilledPromise($easy->response);
+ }
+ private static function invokeStats(EasyHandle $easy) : void
+ {
+ $curlStats = \curl_getinfo($easy->handle);
+ $curlStats['appconnect_time'] = \curl_getinfo($easy->handle, \CURLINFO_APPCONNECT_TIME);
+ $stats = new TransferStats($easy->request, $easy->response, $curlStats['total_time'], $easy->errno, $curlStats);
+ $easy->options['on_stats']($stats);
+ }
+ /**
+ * @param callable(RequestInterface, array): PromiseInterface $handler
+ */
+ private static function finishError(callable $handler, EasyHandle $easy, CurlFactoryInterface $factory) : PromiseInterface
+ {
+ // Get error information and release the handle to the factory.
+ $ctx = ['errno' => $easy->errno, 'error' => \curl_error($easy->handle), 'appconnect_time' => \curl_getinfo($easy->handle, \CURLINFO_APPCONNECT_TIME)] + \curl_getinfo($easy->handle);
+ $ctx[self::CURL_VERSION_STR] = self::getCurlVersion();
+ $factory->release($easy);
+ // Retry when nothing is present or when curl failed to rewind.
+ if (empty($easy->options['_err_message']) && (!$easy->errno || $easy->errno == 65)) {
+ return self::retryFailedRewind($handler, $easy, $ctx);
+ }
+ return self::createRejection($easy, $ctx);
+ }
+ private static function getCurlVersion() : string
+ {
+ static $curlVersion = null;
+ if (null === $curlVersion) {
+ $curlVersion = \curl_version()['version'];
+ }
+ return $curlVersion;
+ }
+ private static function createRejection(EasyHandle $easy, array $ctx) : PromiseInterface
+ {
+ static $connectionErrors = [\CURLE_OPERATION_TIMEOUTED => \true, \CURLE_COULDNT_RESOLVE_HOST => \true, \CURLE_COULDNT_CONNECT => \true, \CURLE_SSL_CONNECT_ERROR => \true, \CURLE_GOT_NOTHING => \true];
+ if ($easy->createResponseException) {
+ return P\Create::rejectionFor(new RequestException('An error was encountered while creating the response', $easy->request, $easy->response, $easy->createResponseException, $ctx));
+ }
+ // If an exception was encountered during the onHeaders event, then
+ // return a rejected promise that wraps that exception.
+ if ($easy->onHeadersException) {
+ return P\Create::rejectionFor(new RequestException('An error was encountered during the on_headers event', $easy->request, $easy->response, $easy->onHeadersException, $ctx));
+ }
+ $uri = $easy->request->getUri();
+ $sanitizedError = self::sanitizeCurlError($ctx['error'] ?? '', $uri);
+ $message = \sprintf('cURL error %s: %s (%s)', $ctx['errno'], $sanitizedError, 'see https://curl.haxx.se/libcurl/c/libcurl-errors.html');
+ if ('' !== $sanitizedError) {
+ $redactedUriString = \WPMailSMTP\Vendor\GuzzleHttp\Psr7\Utils::redactUserInfo($uri)->__toString();
+ if ($redactedUriString !== '' && \false === \strpos($sanitizedError, $redactedUriString)) {
+ $message .= \sprintf(' for %s', $redactedUriString);
+ }
+ }
+ // Create a connection exception if it was a specific error code.
+ $error = isset($connectionErrors[$easy->errno]) ? new ConnectException($message, $easy->request, null, $ctx) : new RequestException($message, $easy->request, $easy->response, null, $ctx);
+ return P\Create::rejectionFor($error);
+ }
+ private static function sanitizeCurlError(string $error, UriInterface $uri) : string
+ {
+ if ('' === $error) {
+ return $error;
+ }
+ $baseUri = $uri->withQuery('')->withFragment('');
+ $baseUriString = $baseUri->__toString();
+ if ('' === $baseUriString) {
+ return $error;
+ }
+ $redactedUriString = \WPMailSMTP\Vendor\GuzzleHttp\Psr7\Utils::redactUserInfo($baseUri)->__toString();
+ return \str_replace($baseUriString, $redactedUriString, $error);
+ }
+ /**
+ * @return array
+ */
+ private function getDefaultConf(EasyHandle $easy) : array
+ {
+ $conf = ['_headers' => $easy->request->getHeaders(), \CURLOPT_CUSTOMREQUEST => $easy->request->getMethod(), \CURLOPT_URL => (string) $easy->request->getUri()->withFragment(''), \CURLOPT_RETURNTRANSFER => \false, \CURLOPT_HEADER => \false, \CURLOPT_CONNECTTIMEOUT => 300];
+ if (\defined('CURLOPT_PROTOCOLS')) {
+ $conf[\CURLOPT_PROTOCOLS] = \CURLPROTO_HTTP | \CURLPROTO_HTTPS;
+ }
+ $version = $easy->request->getProtocolVersion();
+ if ('2' === $version || '2.0' === $version) {
+ $conf[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_2_0;
+ } elseif ('1.1' === $version) {
+ $conf[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_1_1;
+ } else {
+ $conf[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_1_0;
+ }
+ return $conf;
+ }
+ private function applyMethod(EasyHandle $easy, array &$conf) : void
+ {
+ $body = $easy->request->getBody();
+ $size = $body->getSize();
+ if ($size === null || $size > 0) {
+ $this->applyBody($easy->request, $easy->options, $conf);
+ return;
+ }
+ $method = $easy->request->getMethod();
+ if ($method === 'PUT' || $method === 'POST') {
+ // See https://datatracker.ietf.org/doc/html/rfc7230#section-3.3.2
+ if (!$easy->request->hasHeader('Content-Length')) {
+ $conf[\CURLOPT_HTTPHEADER][] = 'Content-Length: 0';
+ }
+ } elseif ($method === 'HEAD') {
+ $conf[\CURLOPT_NOBODY] = \true;
+ unset($conf[\CURLOPT_WRITEFUNCTION], $conf[\CURLOPT_READFUNCTION], $conf[\CURLOPT_FILE], $conf[\CURLOPT_INFILE]);
+ }
+ }
+ private function applyBody(RequestInterface $request, array $options, array &$conf) : void
+ {
+ $size = $request->hasHeader('Content-Length') ? (int) $request->getHeaderLine('Content-Length') : null;
+ // Send the body as a string if the size is less than 1MB OR if the
+ // [curl][body_as_string] request value is set.
+ if ($size !== null && $size < 1000000 || !empty($options['_body_as_string'])) {
+ $conf[\CURLOPT_POSTFIELDS] = (string) $request->getBody();
+ // Don't duplicate the Content-Length header
+ $this->removeHeader('Content-Length', $conf);
+ $this->removeHeader('Transfer-Encoding', $conf);
+ } else {
+ $conf[\CURLOPT_UPLOAD] = \true;
+ if ($size !== null) {
+ $conf[\CURLOPT_INFILESIZE] = $size;
+ $this->removeHeader('Content-Length', $conf);
+ }
+ $body = $request->getBody();
+ if ($body->isSeekable()) {
+ $body->rewind();
+ }
+ $conf[\CURLOPT_READFUNCTION] = static function ($ch, $fd, $length) use($body) {
+ return $body->read($length);
+ };
+ }
+ // If the Expect header is not present, prevent curl from adding it
+ if (!$request->hasHeader('Expect')) {
+ $conf[\CURLOPT_HTTPHEADER][] = 'Expect:';
+ }
+ // cURL sometimes adds a content-type by default. Prevent this.
+ if (!$request->hasHeader('Content-Type')) {
+ $conf[\CURLOPT_HTTPHEADER][] = 'Content-Type:';
+ }
+ }
+ private function applyHeaders(EasyHandle $easy, array &$conf) : void
+ {
+ foreach ($conf['_headers'] as $name => $values) {
+ foreach ($values as $value) {
+ $value = (string) $value;
+ if ($value === '') {
+ // cURL requires a special format for empty headers.
+ // See https://github.com/guzzle/guzzle/issues/1882 for more details.
+ $conf[\CURLOPT_HTTPHEADER][] = "{$name};";
+ } else {
+ $conf[\CURLOPT_HTTPHEADER][] = "{$name}: {$value}";
+ }
+ }
+ }
+ // Remove the Accept header if one was not set
+ if (!$easy->request->hasHeader('Accept')) {
+ $conf[\CURLOPT_HTTPHEADER][] = 'Accept:';
+ }
+ }
+ /**
+ * Remove a header from the options array.
+ *
+ * @param string $name Case-insensitive header to remove
+ * @param array $options Array of options to modify
+ */
+ private function removeHeader(string $name, array &$options) : void
+ {
+ foreach (\array_keys($options['_headers']) as $key) {
+ if (!\strcasecmp($key, $name)) {
+ unset($options['_headers'][$key]);
+ return;
+ }
+ }
+ }
+ private function applyHandlerOptions(EasyHandle $easy, array &$conf) : void
+ {
+ $options = $easy->options;
+ if (isset($options['verify'])) {
+ if ($options['verify'] === \false) {
+ unset($conf[\CURLOPT_CAINFO]);
+ $conf[\CURLOPT_SSL_VERIFYHOST] = 0;
+ $conf[\CURLOPT_SSL_VERIFYPEER] = \false;
+ } else {
+ $conf[\CURLOPT_SSL_VERIFYHOST] = 2;
+ $conf[\CURLOPT_SSL_VERIFYPEER] = \true;
+ if (\is_string($options['verify'])) {
+ // Throw an error if the file/folder/link path is not valid or doesn't exist.
+ if (!\file_exists($options['verify'])) {
+ throw new \InvalidArgumentException("SSL CA bundle not found: {$options['verify']}");
+ }
+ // If it's a directory or a link to a directory use CURLOPT_CAPATH.
+ // If not, it's probably a file, or a link to a file, so use CURLOPT_CAINFO.
+ if (\is_dir($options['verify']) || \is_link($options['verify']) === \true && ($verifyLink = \readlink($options['verify'])) !== \false && \is_dir($verifyLink)) {
+ $conf[\CURLOPT_CAPATH] = $options['verify'];
+ } else {
+ $conf[\CURLOPT_CAINFO] = $options['verify'];
+ }
+ }
+ }
+ }
+ if (!isset($options['curl'][\CURLOPT_ENCODING]) && !empty($options['decode_content'])) {
+ $accept = $easy->request->getHeaderLine('Accept-Encoding');
+ if ($accept) {
+ $conf[\CURLOPT_ENCODING] = $accept;
+ } else {
+ // The empty string enables all available decoders and implicitly
+ // sets a matching 'Accept-Encoding' header.
+ $conf[\CURLOPT_ENCODING] = '';
+ // But as the user did not specify any encoding preference,
+ // let's leave it up to server by preventing curl from sending
+ // the header, which will be interpreted as 'Accept-Encoding: *'.
+ // https://www.rfc-editor.org/rfc/rfc9110#field.accept-encoding
+ $conf[\CURLOPT_HTTPHEADER][] = 'Accept-Encoding:';
+ }
+ }
+ if (!isset($options['sink'])) {
+ // Use a default temp stream if no sink was set.
+ $options['sink'] = \WPMailSMTP\Vendor\GuzzleHttp\Psr7\Utils::tryFopen('php://temp', 'w+');
+ }
+ $sink = $options['sink'];
+ if (!\is_string($sink)) {
+ $sink = \WPMailSMTP\Vendor\GuzzleHttp\Psr7\Utils::streamFor($sink);
+ } elseif (!\is_dir(\dirname($sink))) {
+ // Ensure that the directory exists before failing in curl.
+ throw new \RuntimeException(\sprintf('Directory %s does not exist for sink value of %s', \dirname($sink), $sink));
+ } else {
+ $sink = new LazyOpenStream($sink, 'w+');
+ }
+ $easy->sink = $sink;
+ $conf[\CURLOPT_WRITEFUNCTION] = static function ($ch, $write) use($sink) : int {
+ return $sink->write($write);
+ };
+ $timeoutRequiresNoSignal = \false;
+ if (isset($options['timeout'])) {
+ $timeoutRequiresNoSignal |= $options['timeout'] < 1;
+ $conf[\CURLOPT_TIMEOUT_MS] = $options['timeout'] * 1000;
+ }
+ // CURL default value is CURL_IPRESOLVE_WHATEVER
+ if (isset($options['force_ip_resolve'])) {
+ if ('v4' === $options['force_ip_resolve']) {
+ $conf[\CURLOPT_IPRESOLVE] = \CURL_IPRESOLVE_V4;
+ } elseif ('v6' === $options['force_ip_resolve']) {
+ $conf[\CURLOPT_IPRESOLVE] = \CURL_IPRESOLVE_V6;
+ }
+ }
+ if (isset($options['connect_timeout'])) {
+ $timeoutRequiresNoSignal |= $options['connect_timeout'] < 1;
+ $conf[\CURLOPT_CONNECTTIMEOUT_MS] = $options['connect_timeout'] * 1000;
+ }
+ if ($timeoutRequiresNoSignal && \strtoupper(\substr(\PHP_OS, 0, 3)) !== 'WIN') {
+ $conf[\CURLOPT_NOSIGNAL] = \true;
+ }
+ if (isset($options['proxy'])) {
+ if (!\is_array($options['proxy'])) {
+ $conf[\CURLOPT_PROXY] = $options['proxy'];
+ } else {
+ $scheme = $easy->request->getUri()->getScheme();
+ if (isset($options['proxy'][$scheme])) {
+ $host = $easy->request->getUri()->getHost();
+ if (isset($options['proxy']['no']) && Utils::isHostInNoProxy($host, $options['proxy']['no'])) {
+ unset($conf[\CURLOPT_PROXY]);
+ } else {
+ $conf[\CURLOPT_PROXY] = $options['proxy'][$scheme];
+ }
+ }
+ }
+ }
+ if (isset($options['crypto_method'])) {
+ $protocolVersion = $easy->request->getProtocolVersion();
+ // If HTTP/2, upgrade TLS 1.0 and 1.1 to 1.2
+ if ('2' === $protocolVersion || '2.0' === $protocolVersion) {
+ if (\STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT === $options['crypto_method'] || \STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT === $options['crypto_method'] || \STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT === $options['crypto_method']) {
+ $conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_2;
+ } elseif (\defined('STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT') && \STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT === $options['crypto_method']) {
+ if (!self::supportsTls13()) {
+ throw new \InvalidArgumentException('Invalid crypto_method request option: TLS 1.3 not supported by your version of cURL');
+ }
+ $conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_3;
+ } else {
+ throw new \InvalidArgumentException('Invalid crypto_method request option: unknown version provided');
+ }
+ } elseif (\STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT === $options['crypto_method']) {
+ $conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_0;
+ } elseif (\STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT === $options['crypto_method']) {
+ $conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_1;
+ } elseif (\STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT === $options['crypto_method']) {
+ if (!self::supportsTls12()) {
+ throw new \InvalidArgumentException('Invalid crypto_method request option: TLS 1.2 not supported by your version of cURL');
+ }
+ $conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_2;
+ } elseif (\defined('STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT') && \STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT === $options['crypto_method']) {
+ if (!self::supportsTls13()) {
+ throw new \InvalidArgumentException('Invalid crypto_method request option: TLS 1.3 not supported by your version of cURL');
+ }
+ $conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_3;
+ } else {
+ throw new \InvalidArgumentException('Invalid crypto_method request option: unknown version provided');
+ }
+ }
+ if (isset($options['cert'])) {
+ $cert = $options['cert'];
+ if (\is_array($cert)) {
+ $conf[\CURLOPT_SSLCERTPASSWD] = $cert[1];
+ $cert = $cert[0];
+ }
+ if (!\file_exists($cert)) {
+ throw new \InvalidArgumentException("SSL certificate not found: {$cert}");
+ }
+ // OpenSSL (versions 0.9.3 and later) also support "P12" for PKCS#12-encoded files.
+ // see https://curl.se/libcurl/c/CURLOPT_SSLCERTTYPE.html
+ $ext = \pathinfo($cert, \PATHINFO_EXTENSION);
+ if (\preg_match('#^(der|p12)$#i', $ext)) {
+ $conf[\CURLOPT_SSLCERTTYPE] = \strtoupper($ext);
+ }
+ $conf[\CURLOPT_SSLCERT] = $cert;
+ }
+ if (isset($options['ssl_key'])) {
+ if (\is_array($options['ssl_key'])) {
+ if (\count($options['ssl_key']) === 2) {
+ [$sslKey, $conf[\CURLOPT_SSLKEYPASSWD]] = $options['ssl_key'];
+ } else {
+ [$sslKey] = $options['ssl_key'];
+ }
+ }
+ $sslKey = $sslKey ?? $options['ssl_key'];
+ if (!\file_exists($sslKey)) {
+ throw new \InvalidArgumentException("SSL private key not found: {$sslKey}");
+ }
+ $conf[\CURLOPT_SSLKEY] = $sslKey;
+ }
+ if (isset($options['progress'])) {
+ $progress = $options['progress'];
+ if (!\is_callable($progress)) {
+ throw new \InvalidArgumentException('progress client option must be callable');
+ }
+ $conf[\CURLOPT_NOPROGRESS] = \false;
+ $conf[\CURLOPT_PROGRESSFUNCTION] = static function ($resource, int $downloadSize, int $downloaded, int $uploadSize, int $uploaded) use($progress) {
+ $progress($downloadSize, $downloaded, $uploadSize, $uploaded);
+ };
+ }
+ if (!empty($options['debug'])) {
+ $conf[\CURLOPT_STDERR] = Utils::debugResource($options['debug']);
+ $conf[\CURLOPT_VERBOSE] = \true;
+ }
+ }
+ /**
+ * This function ensures that a response was set on a transaction. If one
+ * was not set, then the request is retried if possible. This error
+ * typically means you are sending a payload, curl encountered a
+ * "Connection died, retrying a fresh connect" error, tried to rewind the
+ * stream, and then encountered a "necessary data rewind wasn't possible"
+ * error, causing the request to be sent through curl_multi_info_read()
+ * without an error status.
+ *
+ * @param callable(RequestInterface, array): PromiseInterface $handler
+ */
+ private static function retryFailedRewind(callable $handler, EasyHandle $easy, array $ctx) : PromiseInterface
+ {
+ try {
+ // Only rewind if the body has been read from.
+ $body = $easy->request->getBody();
+ if ($body->tell() > 0) {
+ $body->rewind();
+ }
+ } catch (\RuntimeException $e) {
+ $ctx['error'] = 'The connection unexpectedly failed without ' . 'providing an error. The request would have been retried, ' . 'but attempting to rewind the request body failed. ' . 'Exception: ' . $e;
+ return self::createRejection($easy, $ctx);
+ }
+ // Retry no more than 3 times before giving up.
+ if (!isset($easy->options['_curl_retries'])) {
+ $easy->options['_curl_retries'] = 1;
+ } elseif ($easy->options['_curl_retries'] == 2) {
+ $ctx['error'] = 'The cURL request was retried 3 times ' . 'and did not succeed. The most likely reason for the failure ' . 'is that cURL was unable to rewind the body of the request ' . 'and subsequent retries resulted in the same error. Turn on ' . 'the debug option to see what went wrong. See ' . 'https://bugs.php.net/bug.php?id=47204 for more information.';
+ return self::createRejection($easy, $ctx);
+ } else {
+ ++$easy->options['_curl_retries'];
+ }
+ return $handler($easy->request, $easy->options);
+ }
+ private function createHeaderFn(EasyHandle $easy) : callable
+ {
+ if (isset($easy->options['on_headers'])) {
+ $onHeaders = $easy->options['on_headers'];
+ if (!\is_callable($onHeaders)) {
+ throw new \InvalidArgumentException('on_headers must be callable');
+ }
+ } else {
+ $onHeaders = null;
+ }
+ return static function ($ch, $h) use($onHeaders, $easy, &$startingResponse) {
+ $value = \trim($h);
+ if ($value === '') {
+ $startingResponse = \true;
+ try {
+ $easy->createResponse();
+ } catch (\Exception $e) {
+ $easy->createResponseException = $e;
+ return -1;
+ }
+ if ($onHeaders !== null) {
+ try {
+ $onHeaders($easy->response);
+ } catch (\Exception $e) {
+ // Associate the exception with the handle and trigger
+ // a curl header write error by returning 0.
+ $easy->onHeadersException = $e;
+ return -1;
+ }
+ }
+ } elseif ($startingResponse) {
+ $startingResponse = \false;
+ $easy->headers = [$value];
+ } else {
+ $easy->headers[] = $value;
+ }
+ return \strlen($h);
+ };
+ }
+ public function __destruct()
+ {
+ foreach ($this->handles as $id => $handle) {
+ if (\PHP_VERSION_ID < 80000) {
+ \curl_close($handle);
+ }
+ unset($this->handles[$id]);
+ }
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/Handler/CurlFactoryInterface.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/Handler/CurlFactoryInterface.php
new file mode 100755
index 00000000..d0ee0066
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/Handler/CurlFactoryInterface.php
@@ -0,0 +1,23 @@
+factory = $options['handle_factory'] ?? new CurlFactory(3);
+ }
+ public function __invoke(RequestInterface $request, array $options) : PromiseInterface
+ {
+ if (isset($options['delay'])) {
+ \usleep($options['delay'] * 1000);
+ }
+ $easy = $this->factory->create($request, $options);
+ \curl_exec($easy->handle);
+ $easy->errno = \curl_errno($easy->handle);
+ return CurlFactory::finish($this, $easy, $this->factory);
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php
new file mode 100755
index 00000000..328eb66f
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php
@@ -0,0 +1,237 @@
+ An array of delay times, indexed by handle id in `addRequest`.
+ *
+ * @see CurlMultiHandler::addRequest
+ */
+ private $delays = [];
+ /**
+ * @var array An associative array of CURLMOPT_* options and corresponding values for curl_multi_setopt()
+ */
+ private $options = [];
+ /** @var resource|\CurlMultiHandle */
+ private $_mh;
+ /**
+ * This handler accepts the following options:
+ *
+ * - handle_factory: An optional factory used to create curl handles
+ * - select_timeout: Optional timeout (in seconds) to block before timing
+ * out while selecting curl handles. Defaults to 1 second.
+ * - options: An associative array of CURLMOPT_* options and
+ * corresponding values for curl_multi_setopt()
+ */
+ public function __construct(array $options = [])
+ {
+ $this->factory = $options['handle_factory'] ?? new CurlFactory(50);
+ if (isset($options['select_timeout'])) {
+ $this->selectTimeout = $options['select_timeout'];
+ } elseif ($selectTimeout = Utils::getenv('GUZZLE_CURL_SELECT_TIMEOUT')) {
+ @\trigger_error('Since guzzlehttp/guzzle 7.2.0: Using environment variable GUZZLE_CURL_SELECT_TIMEOUT is deprecated. Use option "select_timeout" instead.', \E_USER_DEPRECATED);
+ $this->selectTimeout = (int) $selectTimeout;
+ } else {
+ $this->selectTimeout = 1;
+ }
+ $this->options = $options['options'] ?? [];
+ // unsetting the property forces the first access to go through
+ // __get().
+ unset($this->_mh);
+ }
+ /**
+ * @param string $name
+ *
+ * @return resource|\CurlMultiHandle
+ *
+ * @throws \BadMethodCallException when another field as `_mh` will be gotten
+ * @throws \RuntimeException when curl can not initialize a multi handle
+ */
+ public function __get($name)
+ {
+ if ($name !== '_mh') {
+ throw new \BadMethodCallException("Can not get other property as '_mh'.");
+ }
+ $multiHandle = \curl_multi_init();
+ if (\false === $multiHandle) {
+ throw new \RuntimeException('Can not initialize curl multi handle.');
+ }
+ $this->_mh = $multiHandle;
+ foreach ($this->options as $option => $value) {
+ // A warning is raised in case of a wrong option.
+ \curl_multi_setopt($this->_mh, $option, $value);
+ }
+ return $this->_mh;
+ }
+ public function __destruct()
+ {
+ if (isset($this->_mh)) {
+ \curl_multi_close($this->_mh);
+ unset($this->_mh);
+ }
+ }
+ public function __invoke(RequestInterface $request, array $options) : PromiseInterface
+ {
+ $easy = $this->factory->create($request, $options);
+ $id = (int) $easy->handle;
+ $promise = new Promise([$this, 'execute'], function () use($id) {
+ return $this->cancel($id);
+ });
+ $this->addRequest(['easy' => $easy, 'deferred' => $promise]);
+ return $promise;
+ }
+ /**
+ * Ticks the curl event loop.
+ */
+ public function tick() : void
+ {
+ // Add any delayed handles if needed.
+ if ($this->delays) {
+ $currentTime = Utils::currentTime();
+ foreach ($this->delays as $id => $delay) {
+ if ($currentTime >= $delay) {
+ unset($this->delays[$id]);
+ \curl_multi_add_handle($this->_mh, $this->handles[$id]['easy']->handle);
+ }
+ }
+ }
+ // Run curl_multi_exec in the queue to enable other async tasks to run
+ P\Utils::queue()->add(Closure::fromCallable([$this, 'tickInQueue']));
+ // Step through the task queue which may add additional requests.
+ P\Utils::queue()->run();
+ if ($this->active && \curl_multi_select($this->_mh, $this->selectTimeout) === -1) {
+ // Perform a usleep if a select returns -1.
+ // See: https://bugs.php.net/bug.php?id=61141
+ \usleep(250);
+ }
+ while (\curl_multi_exec($this->_mh, $this->active) === \CURLM_CALL_MULTI_PERFORM) {
+ // Prevent busy looping for slow HTTP requests.
+ \curl_multi_select($this->_mh, $this->selectTimeout);
+ }
+ $this->processMessages();
+ }
+ /**
+ * Runs \curl_multi_exec() inside the event loop, to prevent busy looping
+ */
+ private function tickInQueue() : void
+ {
+ if (\curl_multi_exec($this->_mh, $this->active) === \CURLM_CALL_MULTI_PERFORM) {
+ \curl_multi_select($this->_mh, 0);
+ P\Utils::queue()->add(Closure::fromCallable([$this, 'tickInQueue']));
+ }
+ }
+ /**
+ * Runs until all outstanding connections have completed.
+ */
+ public function execute() : void
+ {
+ $queue = P\Utils::queue();
+ while ($this->handles || !$queue->isEmpty()) {
+ // If there are no transfers, then sleep for the next delay
+ if (!$this->active && $this->delays) {
+ \usleep($this->timeToNext());
+ }
+ $this->tick();
+ }
+ }
+ private function addRequest(array $entry) : void
+ {
+ $easy = $entry['easy'];
+ $id = (int) $easy->handle;
+ $this->handles[$id] = $entry;
+ if (empty($easy->options['delay'])) {
+ \curl_multi_add_handle($this->_mh, $easy->handle);
+ } else {
+ $this->delays[$id] = Utils::currentTime() + $easy->options['delay'] / 1000;
+ }
+ }
+ /**
+ * Cancels a handle from sending and removes references to it.
+ *
+ * @param int $id Handle ID to cancel and remove.
+ *
+ * @return bool True on success, false on failure.
+ */
+ private function cancel($id) : bool
+ {
+ if (!\is_int($id)) {
+ trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing an integer to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__);
+ }
+ // Cannot cancel if it has been processed.
+ if (!isset($this->handles[$id])) {
+ return \false;
+ }
+ $handle = $this->handles[$id]['easy']->handle;
+ unset($this->delays[$id], $this->handles[$id]);
+ \curl_multi_remove_handle($this->_mh, $handle);
+ if (\PHP_VERSION_ID < 80000) {
+ \curl_close($handle);
+ }
+ return \true;
+ }
+ private function processMessages() : void
+ {
+ while ($done = \curl_multi_info_read($this->_mh)) {
+ if ($done['msg'] !== \CURLMSG_DONE) {
+ // if it's not done, then it would be premature to remove the handle. ref https://github.com/guzzle/guzzle/pull/2892#issuecomment-945150216
+ continue;
+ }
+ $id = (int) $done['handle'];
+ \curl_multi_remove_handle($this->_mh, $done['handle']);
+ if (!isset($this->handles[$id])) {
+ // Probably was cancelled.
+ continue;
+ }
+ $entry = $this->handles[$id];
+ unset($this->handles[$id], $this->delays[$id]);
+ $entry['easy']->errno = $done['result'];
+ $entry['deferred']->resolve(CurlFactory::finish($this, $entry['easy'], $this->factory));
+ }
+ }
+ private function timeToNext() : int
+ {
+ $currentTime = Utils::currentTime();
+ $nextTime = \PHP_INT_MAX;
+ foreach ($this->delays as $time) {
+ if ($time < $nextTime) {
+ $nextTime = $time;
+ }
+ }
+ return (int) \max(0, $nextTime - $currentTime) * 1000000;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/Handler/EasyHandle.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/Handler/EasyHandle.php
new file mode 100755
index 00000000..d785c64a
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/Handler/EasyHandle.php
@@ -0,0 +1,91 @@
+headers);
+ $normalizedKeys = Utils::normalizeHeaderKeys($headers);
+ if (!empty($this->options['decode_content']) && isset($normalizedKeys['content-encoding'])) {
+ $headers['x-encoded-content-encoding'] = $headers[$normalizedKeys['content-encoding']];
+ unset($headers[$normalizedKeys['content-encoding']]);
+ if (isset($normalizedKeys['content-length'])) {
+ $headers['x-encoded-content-length'] = $headers[$normalizedKeys['content-length']];
+ $bodyLength = (int) $this->sink->getSize();
+ if ($bodyLength) {
+ $headers[$normalizedKeys['content-length']] = $bodyLength;
+ } else {
+ unset($headers[$normalizedKeys['content-length']]);
+ }
+ }
+ }
+ // Attach a response to the easy handle with the parsed headers.
+ $this->response = new Response($status, $headers, $this->sink, $ver, $reason);
+ }
+ /**
+ * @param string $name
+ *
+ * @return void
+ *
+ * @throws \BadMethodCallException
+ */
+ public function __get($name)
+ {
+ $msg = $name === 'handle' ? 'The EasyHandle has been released' : 'Invalid property: ' . $name;
+ throw new \BadMethodCallException($msg);
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/Handler/HeaderProcessor.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/Handler/HeaderProcessor.php
new file mode 100755
index 00000000..2cb00fc0
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/Handler/HeaderProcessor.php
@@ -0,0 +1,36 @@
+|null $queue The parameters to be passed to the append function, as an indexed array.
+ * @param callable|null $onFulfilled Callback to invoke when the return value is fulfilled.
+ * @param callable|null $onRejected Callback to invoke when the return value is rejected.
+ */
+ public function __construct(?array $queue = null, ?callable $onFulfilled = null, ?callable $onRejected = null)
+ {
+ $this->onFulfilled = $onFulfilled;
+ $this->onRejected = $onRejected;
+ if ($queue) {
+ // array_values included for BC
+ $this->append(...\array_values($queue));
+ }
+ }
+ public function __invoke(RequestInterface $request, array $options) : PromiseInterface
+ {
+ if (!$this->queue) {
+ throw new \OutOfBoundsException('Mock queue is empty');
+ }
+ if (isset($options['delay']) && \is_numeric($options['delay'])) {
+ \usleep((int) $options['delay'] * 1000);
+ }
+ $this->lastRequest = $request;
+ $this->lastOptions = $options;
+ $response = \array_shift($this->queue);
+ if (isset($options['on_headers'])) {
+ if (!\is_callable($options['on_headers'])) {
+ throw new \InvalidArgumentException('on_headers must be callable');
+ }
+ try {
+ $options['on_headers']($response);
+ } catch (\Exception $e) {
+ $msg = 'An error was encountered during the on_headers event';
+ $response = new RequestException($msg, $request, $response, $e);
+ }
+ }
+ if (\is_callable($response)) {
+ $response = $response($request, $options);
+ }
+ $response = $response instanceof \Throwable ? P\Create::rejectionFor($response) : P\Create::promiseFor($response);
+ return $response->then(function (?ResponseInterface $value) use($request, $options) {
+ $this->invokeStats($request, $options, $value);
+ if ($this->onFulfilled) {
+ ($this->onFulfilled)($value);
+ }
+ if ($value !== null && isset($options['sink'])) {
+ $contents = (string) $value->getBody();
+ $sink = $options['sink'];
+ if (\is_resource($sink)) {
+ \fwrite($sink, $contents);
+ } elseif (\is_string($sink)) {
+ \file_put_contents($sink, $contents);
+ } elseif ($sink instanceof StreamInterface) {
+ $sink->write($contents);
+ }
+ }
+ return $value;
+ }, function ($reason) use($request, $options) {
+ $this->invokeStats($request, $options, null, $reason);
+ if ($this->onRejected) {
+ ($this->onRejected)($reason);
+ }
+ return P\Create::rejectionFor($reason);
+ });
+ }
+ /**
+ * Adds one or more variadic requests, exceptions, callables, or promises
+ * to the queue.
+ *
+ * @param mixed ...$values
+ */
+ public function append(...$values) : void
+ {
+ foreach ($values as $value) {
+ if ($value instanceof ResponseInterface || $value instanceof \Throwable || $value instanceof PromiseInterface || \is_callable($value)) {
+ $this->queue[] = $value;
+ } else {
+ throw new \TypeError('Expected a Response, Promise, Throwable or callable. Found ' . Utils::describeType($value));
+ }
+ }
+ }
+ /**
+ * Get the last received request.
+ */
+ public function getLastRequest() : ?RequestInterface
+ {
+ return $this->lastRequest;
+ }
+ /**
+ * Get the last received request options.
+ */
+ public function getLastOptions() : array
+ {
+ return $this->lastOptions;
+ }
+ /**
+ * Returns the number of remaining items in the queue.
+ */
+ public function count() : int
+ {
+ return \count($this->queue);
+ }
+ public function reset() : void
+ {
+ $this->queue = [];
+ }
+ /**
+ * @param mixed $reason Promise or reason.
+ */
+ private function invokeStats(RequestInterface $request, array $options, ?ResponseInterface $response = null, $reason = null) : void
+ {
+ if (isset($options['on_stats'])) {
+ $transferTime = $options['transfer_time'] ?? 0;
+ $stats = new TransferStats($request, $response, $transferTime, $reason);
+ $options['on_stats']($stats);
+ }
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/Handler/Proxy.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/Handler/Proxy.php
new file mode 100755
index 00000000..20204399
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/Handler/Proxy.php
@@ -0,0 +1,49 @@
+getProtocolVersion();
+ if ('1.0' !== $protocolVersion && '1.1' !== $protocolVersion) {
+ throw new ConnectException(\sprintf('HTTP/%s is not supported by the stream handler.', $protocolVersion), $request);
+ }
+ $startTime = isset($options['on_stats']) ? Utils::currentTime() : null;
+ try {
+ // Does not support the expect header.
+ $request = $request->withoutHeader('Expect');
+ // Append a content-length header if body size is zero to match
+ // the behavior of `CurlHandler`
+ if ((0 === \strcasecmp('PUT', $request->getMethod()) || 0 === \strcasecmp('POST', $request->getMethod())) && 0 === $request->getBody()->getSize()) {
+ $request = $request->withHeader('Content-Length', '0');
+ }
+ return $this->createResponse($request, $options, $this->createStream($request, $options), $startTime);
+ } catch (\InvalidArgumentException $e) {
+ throw $e;
+ } catch (\Exception $e) {
+ // Determine if the error was a networking error.
+ $message = $e->getMessage();
+ // This list can probably get more comprehensive.
+ if (\false !== \strpos($message, 'getaddrinfo') || \false !== \strpos($message, 'Connection refused') || \false !== \strpos($message, "couldn't connect to host") || \false !== \strpos($message, 'connection attempt failed')) {
+ $e = new ConnectException($e->getMessage(), $request, $e);
+ } else {
+ $e = RequestException::wrapException($request, $e);
+ }
+ $this->invokeStats($options, $request, $startTime, null, $e);
+ return P\Create::rejectionFor($e);
+ }
+ }
+ private function invokeStats(array $options, RequestInterface $request, ?float $startTime, ?ResponseInterface $response = null, ?\Throwable $error = null) : void
+ {
+ if (isset($options['on_stats'])) {
+ $stats = new TransferStats($request, $response, Utils::currentTime() - $startTime, $error, []);
+ $options['on_stats']($stats);
+ }
+ }
+ /**
+ * @param resource $stream
+ */
+ private function createResponse(RequestInterface $request, array $options, $stream, ?float $startTime) : PromiseInterface
+ {
+ $hdrs = $this->lastHeaders;
+ $this->lastHeaders = [];
+ try {
+ [$ver, $status, $reason, $headers] = HeaderProcessor::parseHeaders($hdrs);
+ } catch (\Exception $e) {
+ return P\Create::rejectionFor(new RequestException('An error was encountered while creating the response', $request, null, $e));
+ }
+ [$stream, $headers] = $this->checkDecode($options, $headers, $stream);
+ $stream = Psr7\Utils::streamFor($stream);
+ $sink = $stream;
+ if (\strcasecmp('HEAD', $request->getMethod())) {
+ $sink = $this->createSink($stream, $options);
+ }
+ try {
+ $response = new Psr7\Response($status, $headers, $sink, $ver, $reason);
+ } catch (\Exception $e) {
+ return P\Create::rejectionFor(new RequestException('An error was encountered while creating the response', $request, null, $e));
+ }
+ if (isset($options['on_headers'])) {
+ try {
+ $options['on_headers']($response);
+ } catch (\Exception $e) {
+ return P\Create::rejectionFor(new RequestException('An error was encountered during the on_headers event', $request, $response, $e));
+ }
+ }
+ // Do not drain when the request is a HEAD request because they have
+ // no body.
+ if ($sink !== $stream) {
+ $this->drain($stream, $sink, $response->getHeaderLine('Content-Length'));
+ }
+ $this->invokeStats($options, $request, $startTime, $response, null);
+ return new FulfilledPromise($response);
+ }
+ private function createSink(StreamInterface $stream, array $options) : StreamInterface
+ {
+ if (!empty($options['stream'])) {
+ return $stream;
+ }
+ $sink = $options['sink'] ?? Psr7\Utils::tryFopen('php://temp', 'r+');
+ return \is_string($sink) ? new Psr7\LazyOpenStream($sink, 'w+') : Psr7\Utils::streamFor($sink);
+ }
+ /**
+ * @param resource $stream
+ */
+ private function checkDecode(array $options, array $headers, $stream) : array
+ {
+ // Automatically decode responses when instructed.
+ if (!empty($options['decode_content'])) {
+ $normalizedKeys = Utils::normalizeHeaderKeys($headers);
+ if (isset($normalizedKeys['content-encoding'])) {
+ $encoding = $headers[$normalizedKeys['content-encoding']];
+ if ($encoding[0] === 'gzip' || $encoding[0] === 'deflate') {
+ $stream = new Psr7\InflateStream(Psr7\Utils::streamFor($stream));
+ $headers['x-encoded-content-encoding'] = $headers[$normalizedKeys['content-encoding']];
+ // Remove content-encoding header
+ unset($headers[$normalizedKeys['content-encoding']]);
+ // Fix content-length header
+ if (isset($normalizedKeys['content-length'])) {
+ $headers['x-encoded-content-length'] = $headers[$normalizedKeys['content-length']];
+ $length = (int) $stream->getSize();
+ if ($length === 0) {
+ unset($headers[$normalizedKeys['content-length']]);
+ } else {
+ $headers[$normalizedKeys['content-length']] = [$length];
+ }
+ }
+ }
+ }
+ }
+ return [$stream, $headers];
+ }
+ /**
+ * Drains the source stream into the "sink" client option.
+ *
+ * @param string $contentLength Header specifying the amount of
+ * data to read.
+ *
+ * @throws \RuntimeException when the sink option is invalid.
+ */
+ private function drain(StreamInterface $source, StreamInterface $sink, string $contentLength) : StreamInterface
+ {
+ // If a content-length header is provided, then stop reading once
+ // that number of bytes has been read. This can prevent infinitely
+ // reading from a stream when dealing with servers that do not honor
+ // Connection: Close headers.
+ Psr7\Utils::copyToStream($source, $sink, \strlen($contentLength) > 0 && (int) $contentLength > 0 ? (int) $contentLength : -1);
+ $sink->seek(0);
+ $source->close();
+ return $sink;
+ }
+ /**
+ * Create a resource and check to ensure it was created successfully
+ *
+ * @param callable $callback Callable that returns stream resource
+ *
+ * @return resource
+ *
+ * @throws \RuntimeException on error
+ */
+ private function createResource(callable $callback)
+ {
+ $errors = [];
+ \set_error_handler(static function ($_, $msg, $file, $line) use(&$errors) : bool {
+ $errors[] = ['message' => $msg, 'file' => $file, 'line' => $line];
+ return \true;
+ });
+ try {
+ $resource = $callback();
+ } finally {
+ \restore_error_handler();
+ }
+ if (!$resource) {
+ $message = 'Error creating resource: ';
+ foreach ($errors as $err) {
+ foreach ($err as $key => $value) {
+ $message .= "[{$key}] {$value}" . \PHP_EOL;
+ }
+ }
+ throw new \RuntimeException(\trim($message));
+ }
+ return $resource;
+ }
+ /**
+ * @return resource
+ */
+ private function createStream(RequestInterface $request, array $options)
+ {
+ static $methods;
+ if (!$methods) {
+ $methods = \array_flip(\get_class_methods(__CLASS__));
+ }
+ if (!\in_array($request->getUri()->getScheme(), ['http', 'https'])) {
+ throw new RequestException(\sprintf("The scheme '%s' is not supported.", $request->getUri()->getScheme()), $request);
+ }
+ // HTTP/1.1 streams using the PHP stream wrapper require a
+ // Connection: close header
+ if ($request->getProtocolVersion() === '1.1' && !$request->hasHeader('Connection')) {
+ $request = $request->withHeader('Connection', 'close');
+ }
+ // Ensure SSL is verified by default
+ if (!isset($options['verify'])) {
+ $options['verify'] = \true;
+ }
+ $params = [];
+ $context = $this->getDefaultContext($request);
+ if (isset($options['on_headers']) && !\is_callable($options['on_headers'])) {
+ throw new \InvalidArgumentException('on_headers must be callable');
+ }
+ if (!empty($options)) {
+ foreach ($options as $key => $value) {
+ $method = "add_{$key}";
+ if (isset($methods[$method])) {
+ $this->{$method}($request, $context, $value, $params);
+ }
+ }
+ }
+ if (isset($options['stream_context'])) {
+ if (!\is_array($options['stream_context'])) {
+ throw new \InvalidArgumentException('stream_context must be an array');
+ }
+ $context = \array_replace_recursive($context, $options['stream_context']);
+ }
+ // Microsoft NTLM authentication only supported with curl handler
+ if (isset($options['auth'][2]) && 'ntlm' === $options['auth'][2]) {
+ throw new \InvalidArgumentException('Microsoft NTLM authentication only supported with curl handler');
+ }
+ $uri = $this->resolveHost($request, $options);
+ $contextResource = $this->createResource(static function () use($context, $params) {
+ return \stream_context_create($context, $params);
+ });
+ return $this->createResource(function () use($uri, $contextResource, $context, $options, $request) {
+ $resource = @\fopen((string) $uri, 'r', \false, $contextResource);
+ // See https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_the_http_response_header_predefined_variable
+ if (\function_exists('WPMailSMTP\\Vendor\\http_get_last_response_headers')) {
+ /** @var array|null */
+ $http_response_header = \WPMailSMTP\Vendor\http_get_last_response_headers();
+ }
+ $this->lastHeaders = $http_response_header ?? [];
+ if (\false === $resource) {
+ throw new ConnectException(\sprintf('Connection refused for URI %s', $uri), $request, null, $context);
+ }
+ if (isset($options['read_timeout'])) {
+ $readTimeout = $options['read_timeout'];
+ $sec = (int) $readTimeout;
+ $usec = ($readTimeout - $sec) * 100000;
+ \stream_set_timeout($resource, $sec, $usec);
+ }
+ return $resource;
+ });
+ }
+ private function resolveHost(RequestInterface $request, array $options) : UriInterface
+ {
+ $uri = $request->getUri();
+ if (isset($options['force_ip_resolve']) && !\filter_var($uri->getHost(), \FILTER_VALIDATE_IP)) {
+ if ('v4' === $options['force_ip_resolve']) {
+ $records = \dns_get_record($uri->getHost(), \DNS_A);
+ if (\false === $records || !isset($records[0]['ip'])) {
+ throw new ConnectException(\sprintf("Could not resolve IPv4 address for host '%s'", $uri->getHost()), $request);
+ }
+ return $uri->withHost($records[0]['ip']);
+ }
+ if ('v6' === $options['force_ip_resolve']) {
+ $records = \dns_get_record($uri->getHost(), \DNS_AAAA);
+ if (\false === $records || !isset($records[0]['ipv6'])) {
+ throw new ConnectException(\sprintf("Could not resolve IPv6 address for host '%s'", $uri->getHost()), $request);
+ }
+ return $uri->withHost('[' . $records[0]['ipv6'] . ']');
+ }
+ }
+ return $uri;
+ }
+ private function getDefaultContext(RequestInterface $request) : array
+ {
+ $headers = '';
+ foreach ($request->getHeaders() as $name => $value) {
+ foreach ($value as $val) {
+ $headers .= "{$name}: {$val}\r\n";
+ }
+ }
+ $context = ['http' => ['method' => $request->getMethod(), 'header' => $headers, 'protocol_version' => $request->getProtocolVersion(), 'ignore_errors' => \true, 'follow_location' => 0], 'ssl' => ['peer_name' => $request->getUri()->getHost()]];
+ $body = (string) $request->getBody();
+ if ('' !== $body) {
+ $context['http']['content'] = $body;
+ // Prevent the HTTP handler from adding a Content-Type header.
+ if (!$request->hasHeader('Content-Type')) {
+ $context['http']['header'] .= "Content-Type:\r\n";
+ }
+ }
+ $context['http']['header'] = \rtrim($context['http']['header']);
+ return $context;
+ }
+ /**
+ * @param mixed $value as passed via Request transfer options.
+ */
+ private function add_proxy(RequestInterface $request, array &$options, $value, array &$params) : void
+ {
+ $uri = null;
+ if (!\is_array($value)) {
+ $uri = $value;
+ } else {
+ $scheme = $request->getUri()->getScheme();
+ if (isset($value[$scheme])) {
+ if (!isset($value['no']) || !Utils::isHostInNoProxy($request->getUri()->getHost(), $value['no'])) {
+ $uri = $value[$scheme];
+ }
+ }
+ }
+ if (!$uri) {
+ return;
+ }
+ $parsed = $this->parse_proxy($uri);
+ $options['http']['proxy'] = $parsed['proxy'];
+ if ($parsed['auth']) {
+ if (!isset($options['http']['header'])) {
+ $options['http']['header'] = [];
+ }
+ $options['http']['header'] .= "\r\nProxy-Authorization: {$parsed['auth']}";
+ }
+ }
+ /**
+ * Parses the given proxy URL to make it compatible with the format PHP's stream context expects.
+ */
+ private function parse_proxy(string $url) : array
+ {
+ $parsed = \parse_url($url);
+ if ($parsed !== \false && isset($parsed['scheme']) && $parsed['scheme'] === 'http') {
+ if (isset($parsed['host']) && isset($parsed['port'])) {
+ $auth = null;
+ if (isset($parsed['user']) && isset($parsed['pass'])) {
+ $auth = \base64_encode("{$parsed['user']}:{$parsed['pass']}");
+ }
+ return ['proxy' => "tcp://{$parsed['host']}:{$parsed['port']}", 'auth' => $auth ? "Basic {$auth}" : null];
+ }
+ }
+ // Return proxy as-is.
+ return ['proxy' => $url, 'auth' => null];
+ }
+ /**
+ * @param mixed $value as passed via Request transfer options.
+ */
+ private function add_timeout(RequestInterface $request, array &$options, $value, array &$params) : void
+ {
+ if ($value > 0) {
+ $options['http']['timeout'] = $value;
+ }
+ }
+ /**
+ * @param mixed $value as passed via Request transfer options.
+ */
+ private function add_crypto_method(RequestInterface $request, array &$options, $value, array &$params) : void
+ {
+ if ($value === \STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT || $value === \STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT || $value === \STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT || \defined('STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT') && $value === \STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT) {
+ $options['http']['crypto_method'] = $value;
+ return;
+ }
+ throw new \InvalidArgumentException('Invalid crypto_method request option: unknown version provided');
+ }
+ /**
+ * @param mixed $value as passed via Request transfer options.
+ */
+ private function add_verify(RequestInterface $request, array &$options, $value, array &$params) : void
+ {
+ if ($value === \false) {
+ $options['ssl']['verify_peer'] = \false;
+ $options['ssl']['verify_peer_name'] = \false;
+ return;
+ }
+ if (\is_string($value)) {
+ $options['ssl']['cafile'] = $value;
+ if (!\file_exists($value)) {
+ throw new \RuntimeException("SSL CA bundle not found: {$value}");
+ }
+ } elseif ($value !== \true) {
+ throw new \InvalidArgumentException('Invalid verify request option');
+ }
+ $options['ssl']['verify_peer'] = \true;
+ $options['ssl']['verify_peer_name'] = \true;
+ $options['ssl']['allow_self_signed'] = \false;
+ }
+ /**
+ * @param mixed $value as passed via Request transfer options.
+ */
+ private function add_cert(RequestInterface $request, array &$options, $value, array &$params) : void
+ {
+ if (\is_array($value)) {
+ $options['ssl']['passphrase'] = $value[1];
+ $value = $value[0];
+ }
+ if (!\file_exists($value)) {
+ throw new \RuntimeException("SSL certificate not found: {$value}");
+ }
+ $options['ssl']['local_cert'] = $value;
+ }
+ /**
+ * @param mixed $value as passed via Request transfer options.
+ */
+ private function add_progress(RequestInterface $request, array &$options, $value, array &$params) : void
+ {
+ self::addNotification($params, static function ($code, $a, $b, $c, $transferred, $total) use($value) {
+ if ($code == \STREAM_NOTIFY_PROGRESS) {
+ // The upload progress cannot be determined. Use 0 for cURL compatibility:
+ // https://curl.se/libcurl/c/CURLOPT_PROGRESSFUNCTION.html
+ $value($total, $transferred, 0, 0);
+ }
+ });
+ }
+ /**
+ * @param mixed $value as passed via Request transfer options.
+ */
+ private function add_debug(RequestInterface $request, array &$options, $value, array &$params) : void
+ {
+ if ($value === \false) {
+ return;
+ }
+ static $map = [\STREAM_NOTIFY_CONNECT => 'CONNECT', \STREAM_NOTIFY_AUTH_REQUIRED => 'AUTH_REQUIRED', \STREAM_NOTIFY_AUTH_RESULT => 'AUTH_RESULT', \STREAM_NOTIFY_MIME_TYPE_IS => 'MIME_TYPE_IS', \STREAM_NOTIFY_FILE_SIZE_IS => 'FILE_SIZE_IS', \STREAM_NOTIFY_REDIRECTED => 'REDIRECTED', \STREAM_NOTIFY_PROGRESS => 'PROGRESS', \STREAM_NOTIFY_FAILURE => 'FAILURE', \STREAM_NOTIFY_COMPLETED => 'COMPLETED', \STREAM_NOTIFY_RESOLVE => 'RESOLVE'];
+ static $args = ['severity', 'message', 'message_code', 'bytes_transferred', 'bytes_max'];
+ $value = Utils::debugResource($value);
+ $ident = $request->getMethod() . ' ' . $request->getUri()->withFragment('');
+ self::addNotification($params, static function (int $code, ...$passed) use($ident, $value, $map, $args) : void {
+ \fprintf($value, '<%s> [%s] ', $ident, $map[$code]);
+ foreach (\array_filter($passed) as $i => $v) {
+ \fwrite($value, $args[$i] . ': "' . $v . '" ');
+ }
+ \fwrite($value, "\n");
+ });
+ }
+ private static function addNotification(array &$params, callable $notify) : void
+ {
+ // Wrap the existing function if needed.
+ if (!isset($params['notification'])) {
+ $params['notification'] = $notify;
+ } else {
+ $params['notification'] = self::callArray([$params['notification'], $notify]);
+ }
+ }
+ private static function callArray(array $functions) : callable
+ {
+ return static function (...$args) use($functions) {
+ foreach ($functions as $fn) {
+ $fn(...$args);
+ }
+ };
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/HandlerStack.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/HandlerStack.php
new file mode 100755
index 00000000..71d0d10f
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/HandlerStack.php
@@ -0,0 +1,238 @@
+push(Middleware::httpErrors(), 'http_errors');
+ $stack->push(Middleware::redirect(), 'allow_redirects');
+ $stack->push(Middleware::cookies(), 'cookies');
+ $stack->push(Middleware::prepareBody(), 'prepare_body');
+ return $stack;
+ }
+ /**
+ * @param (callable(RequestInterface, array): PromiseInterface)|null $handler Underlying HTTP handler.
+ */
+ public function __construct(?callable $handler = null)
+ {
+ $this->handler = $handler;
+ }
+ /**
+ * Invokes the handler stack as a composed handler
+ *
+ * @return ResponseInterface|PromiseInterface
+ */
+ public function __invoke(RequestInterface $request, array $options)
+ {
+ $handler = $this->resolve();
+ return $handler($request, $options);
+ }
+ /**
+ * Dumps a string representation of the stack.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ $depth = 0;
+ $stack = [];
+ if ($this->handler !== null) {
+ $stack[] = '0) Handler: ' . $this->debugCallable($this->handler);
+ }
+ $result = '';
+ foreach (\array_reverse($this->stack) as $tuple) {
+ ++$depth;
+ $str = "{$depth}) Name: '{$tuple[1]}', ";
+ $str .= 'Function: ' . $this->debugCallable($tuple[0]);
+ $result = "> {$str}\n{$result}";
+ $stack[] = $str;
+ }
+ foreach (\array_keys($stack) as $k) {
+ $result .= "< {$stack[$k]}\n";
+ }
+ return $result;
+ }
+ /**
+ * Set the HTTP handler that actually returns a promise.
+ *
+ * @param callable(RequestInterface, array): PromiseInterface $handler Accepts a request and array of options and
+ * returns a Promise.
+ */
+ public function setHandler(callable $handler) : void
+ {
+ $this->handler = $handler;
+ $this->cached = null;
+ }
+ /**
+ * Returns true if the builder has a handler.
+ */
+ public function hasHandler() : bool
+ {
+ return $this->handler !== null;
+ }
+ /**
+ * Unshift a middleware to the bottom of the stack.
+ *
+ * @param callable(callable): callable $middleware Middleware function
+ * @param string $name Name to register for this middleware.
+ */
+ public function unshift(callable $middleware, ?string $name = null) : void
+ {
+ \array_unshift($this->stack, [$middleware, $name]);
+ $this->cached = null;
+ }
+ /**
+ * Push a middleware to the top of the stack.
+ *
+ * @param callable(callable): callable $middleware Middleware function
+ * @param string $name Name to register for this middleware.
+ */
+ public function push(callable $middleware, string $name = '') : void
+ {
+ $this->stack[] = [$middleware, $name];
+ $this->cached = null;
+ }
+ /**
+ * Add a middleware before another middleware by name.
+ *
+ * @param string $findName Middleware to find
+ * @param callable(callable): callable $middleware Middleware function
+ * @param string $withName Name to register for this middleware.
+ */
+ public function before(string $findName, callable $middleware, string $withName = '') : void
+ {
+ $this->splice($findName, $withName, $middleware, \true);
+ }
+ /**
+ * Add a middleware after another middleware by name.
+ *
+ * @param string $findName Middleware to find
+ * @param callable(callable): callable $middleware Middleware function
+ * @param string $withName Name to register for this middleware.
+ */
+ public function after(string $findName, callable $middleware, string $withName = '') : void
+ {
+ $this->splice($findName, $withName, $middleware, \false);
+ }
+ /**
+ * Remove a middleware by instance or name from the stack.
+ *
+ * @param callable|string $remove Middleware to remove by instance or name.
+ */
+ public function remove($remove) : void
+ {
+ if (!\is_string($remove) && !\is_callable($remove)) {
+ trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing a callable or string to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__);
+ }
+ $this->cached = null;
+ $idx = \is_callable($remove) ? 0 : 1;
+ $this->stack = \array_values(\array_filter($this->stack, static function ($tuple) use($idx, $remove) {
+ return $tuple[$idx] !== $remove;
+ }));
+ }
+ /**
+ * Compose the middleware and handler into a single callable function.
+ *
+ * @return callable(RequestInterface, array): PromiseInterface
+ */
+ public function resolve() : callable
+ {
+ if ($this->cached === null) {
+ if (($prev = $this->handler) === null) {
+ throw new \LogicException('No handler has been specified');
+ }
+ foreach (\array_reverse($this->stack) as $fn) {
+ /** @var callable(RequestInterface, array): PromiseInterface $prev */
+ $prev = $fn[0]($prev);
+ }
+ $this->cached = $prev;
+ }
+ return $this->cached;
+ }
+ private function findByName(string $name) : int
+ {
+ foreach ($this->stack as $k => $v) {
+ if ($v[1] === $name) {
+ return $k;
+ }
+ }
+ throw new \InvalidArgumentException("Middleware not found: {$name}");
+ }
+ /**
+ * Splices a function into the middleware list at a specific position.
+ */
+ private function splice(string $findName, string $withName, callable $middleware, bool $before) : void
+ {
+ $this->cached = null;
+ $idx = $this->findByName($findName);
+ $tuple = [$middleware, $withName];
+ if ($before) {
+ if ($idx === 0) {
+ \array_unshift($this->stack, $tuple);
+ } else {
+ $replacement = [$tuple, $this->stack[$idx]];
+ \array_splice($this->stack, $idx, 1, $replacement);
+ }
+ } elseif ($idx === \count($this->stack) - 1) {
+ $this->stack[] = $tuple;
+ } else {
+ $replacement = [$this->stack[$idx], $tuple];
+ \array_splice($this->stack, $idx, 1, $replacement);
+ }
+ }
+ /**
+ * Provides a debug string for a given callable.
+ *
+ * @param callable|string $fn Function to write as a string.
+ */
+ private function debugCallable($fn) : string
+ {
+ if (\is_string($fn)) {
+ return "callable({$fn})";
+ }
+ if (\is_array($fn)) {
+ return \is_string($fn[0]) ? "callable({$fn[0]}::{$fn[1]})" : "callable(['" . \get_class($fn[0]) . "', '{$fn[1]}'])";
+ }
+ /** @var object $fn */
+ return 'callable(' . \spl_object_hash($fn) . ')';
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/MessageFormatter.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/MessageFormatter.php
new file mode 100755
index 00000000..300238a1
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/MessageFormatter.php
@@ -0,0 +1,168 @@
+>>>>>>>\n{request}\n<<<<<<<<\n{response}\n--------\n{error}";
+ public const SHORT = '[{ts}] "{method} {target} HTTP/{version}" {code}';
+ /**
+ * @var string Template used to format log messages
+ */
+ private $template;
+ /**
+ * @param string $template Log message template
+ */
+ public function __construct(?string $template = self::CLF)
+ {
+ $this->template = $template ?: self::CLF;
+ }
+ /**
+ * Returns a formatted message string.
+ *
+ * @param RequestInterface $request Request that was sent
+ * @param ResponseInterface|null $response Response that was received
+ * @param \Throwable|null $error Exception that was received
+ */
+ public function format(RequestInterface $request, ?ResponseInterface $response = null, ?\Throwable $error = null) : string
+ {
+ $cache = [];
+ /** @var string */
+ return \preg_replace_callback('/{\\s*([A-Za-z_\\-\\.0-9]+)\\s*}/', function (array $matches) use($request, $response, $error, &$cache) {
+ if (isset($cache[$matches[1]])) {
+ return $cache[$matches[1]];
+ }
+ $result = '';
+ switch ($matches[1]) {
+ case 'request':
+ $result = Psr7\Message::toString($request);
+ break;
+ case 'response':
+ $result = $response ? Psr7\Message::toString($response) : '';
+ break;
+ case 'req_headers':
+ $result = \trim($request->getMethod() . ' ' . $request->getRequestTarget()) . ' HTTP/' . $request->getProtocolVersion() . "\r\n" . $this->headers($request);
+ break;
+ case 'res_headers':
+ $result = $response ? \sprintf('HTTP/%s %d %s', $response->getProtocolVersion(), $response->getStatusCode(), $response->getReasonPhrase()) . "\r\n" . $this->headers($response) : 'NULL';
+ break;
+ case 'req_body':
+ $result = $request->getBody()->__toString();
+ break;
+ case 'res_body':
+ if (!$response instanceof ResponseInterface) {
+ $result = 'NULL';
+ break;
+ }
+ $body = $response->getBody();
+ if (!$body->isSeekable()) {
+ $result = 'RESPONSE_NOT_LOGGEABLE';
+ break;
+ }
+ $result = $response->getBody()->__toString();
+ break;
+ case 'ts':
+ case 'date_iso_8601':
+ $result = \gmdate('c');
+ break;
+ case 'date_common_log':
+ $result = \date('d/M/Y:H:i:s O');
+ break;
+ case 'method':
+ $result = $request->getMethod();
+ break;
+ case 'version':
+ $result = $request->getProtocolVersion();
+ break;
+ case 'uri':
+ case 'url':
+ $result = $request->getUri()->__toString();
+ break;
+ case 'target':
+ $result = $request->getRequestTarget();
+ break;
+ case 'req_version':
+ $result = $request->getProtocolVersion();
+ break;
+ case 'res_version':
+ $result = $response ? $response->getProtocolVersion() : 'NULL';
+ break;
+ case 'host':
+ $result = $request->getHeaderLine('Host');
+ break;
+ case 'hostname':
+ $result = \gethostname();
+ break;
+ case 'code':
+ $result = $response ? $response->getStatusCode() : 'NULL';
+ break;
+ case 'phrase':
+ $result = $response ? $response->getReasonPhrase() : 'NULL';
+ break;
+ case 'error':
+ $result = $error ? $error->getMessage() : 'NULL';
+ break;
+ default:
+ // handle prefixed dynamic headers
+ if (\strpos($matches[1], 'req_header_') === 0) {
+ $result = $request->getHeaderLine(\substr($matches[1], 11));
+ } elseif (\strpos($matches[1], 'res_header_') === 0) {
+ $result = $response ? $response->getHeaderLine(\substr($matches[1], 11)) : 'NULL';
+ }
+ }
+ $cache[$matches[1]] = $result;
+ return $result;
+ }, $this->template);
+ }
+ /**
+ * Get headers from message as string
+ */
+ private function headers(MessageInterface $message) : string
+ {
+ $result = '';
+ foreach ($message->getHeaders() as $name => $values) {
+ $result .= $name . ': ' . \implode(', ', $values) . "\r\n";
+ }
+ return \trim($result);
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/MessageFormatterInterface.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/MessageFormatterInterface.php
new file mode 100755
index 00000000..70cb64fe
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/MessageFormatterInterface.php
@@ -0,0 +1,17 @@
+withCookieHeader($request);
+ return $handler($request, $options)->then(static function (ResponseInterface $response) use($cookieJar, $request) : ResponseInterface {
+ $cookieJar->extractCookies($request, $response);
+ return $response;
+ });
+ };
+ };
+ }
+ /**
+ * Middleware that throws exceptions for 4xx or 5xx responses when the
+ * "http_errors" request option is set to true.
+ *
+ * @param BodySummarizerInterface|null $bodySummarizer The body summarizer to use in exception messages.
+ *
+ * @return callable(callable): callable Returns a function that accepts the next handler.
+ */
+ public static function httpErrors(?BodySummarizerInterface $bodySummarizer = null) : callable
+ {
+ return static function (callable $handler) use($bodySummarizer) : callable {
+ return static function ($request, array $options) use($handler, $bodySummarizer) {
+ if (empty($options['http_errors'])) {
+ return $handler($request, $options);
+ }
+ return $handler($request, $options)->then(static function (ResponseInterface $response) use($request, $bodySummarizer) {
+ $code = $response->getStatusCode();
+ if ($code < 400) {
+ return $response;
+ }
+ throw RequestException::create($request, $response, null, [], $bodySummarizer);
+ });
+ };
+ };
+ }
+ /**
+ * Middleware that pushes history data to an ArrayAccess container.
+ *
+ * @param array|\ArrayAccess $container Container to hold the history (by reference).
+ *
+ * @return callable(callable): callable Returns a function that accepts the next handler.
+ *
+ * @throws \InvalidArgumentException if container is not an array or ArrayAccess.
+ */
+ public static function history(&$container) : callable
+ {
+ if (!\is_array($container) && !$container instanceof \ArrayAccess) {
+ throw new \InvalidArgumentException('history container must be an array or object implementing ArrayAccess');
+ }
+ return static function (callable $handler) use(&$container) : callable {
+ return static function (RequestInterface $request, array $options) use($handler, &$container) {
+ return $handler($request, $options)->then(static function ($value) use($request, &$container, $options) {
+ $container[] = ['request' => $request, 'response' => $value, 'error' => null, 'options' => $options];
+ return $value;
+ }, static function ($reason) use($request, &$container, $options) {
+ $container[] = ['request' => $request, 'response' => null, 'error' => $reason, 'options' => $options];
+ return P\Create::rejectionFor($reason);
+ });
+ };
+ };
+ }
+ /**
+ * Middleware that invokes a callback before and after sending a request.
+ *
+ * The provided listener cannot modify or alter the response. It simply
+ * "taps" into the chain to be notified before returning the promise. The
+ * before listener accepts a request and options array, and the after
+ * listener accepts a request, options array, and response promise.
+ *
+ * @param callable $before Function to invoke before forwarding the request.
+ * @param callable $after Function invoked after forwarding.
+ *
+ * @return callable Returns a function that accepts the next handler.
+ */
+ public static function tap(?callable $before = null, ?callable $after = null) : callable
+ {
+ return static function (callable $handler) use($before, $after) : callable {
+ return static function (RequestInterface $request, array $options) use($handler, $before, $after) {
+ if ($before) {
+ $before($request, $options);
+ }
+ $response = $handler($request, $options);
+ if ($after) {
+ $after($request, $options, $response);
+ }
+ return $response;
+ };
+ };
+ }
+ /**
+ * Middleware that handles request redirects.
+ *
+ * @return callable Returns a function that accepts the next handler.
+ */
+ public static function redirect() : callable
+ {
+ return static function (callable $handler) : RedirectMiddleware {
+ return new RedirectMiddleware($handler);
+ };
+ }
+ /**
+ * Middleware that retries requests based on the boolean result of
+ * invoking the provided "decider" function.
+ *
+ * If no delay function is provided, a simple implementation of exponential
+ * backoff will be utilized.
+ *
+ * @param callable $decider Function that accepts the number of retries,
+ * a request, [response], and [exception] and
+ * returns true if the request is to be retried.
+ * @param callable $delay Function that accepts the number of retries and
+ * returns the number of milliseconds to delay.
+ *
+ * @return callable Returns a function that accepts the next handler.
+ */
+ public static function retry(callable $decider, ?callable $delay = null) : callable
+ {
+ return static function (callable $handler) use($decider, $delay) : RetryMiddleware {
+ return new RetryMiddleware($decider, $handler, $delay);
+ };
+ }
+ /**
+ * Middleware that logs requests, responses, and errors using a message
+ * formatter.
+ *
+ * @param LoggerInterface $logger Logs messages.
+ * @param MessageFormatterInterface|MessageFormatter $formatter Formatter used to create message strings.
+ * @param string $logLevel Level at which to log requests.
+ *
+ * @phpstan-param \Psr\Log\LogLevel::* $logLevel Level at which to log requests.
+ *
+ * @return callable Returns a function that accepts the next handler.
+ */
+ public static function log(LoggerInterface $logger, $formatter, string $logLevel = 'info') : callable
+ {
+ // To be compatible with Guzzle 7.1.x we need to allow users to pass a MessageFormatter
+ if (!$formatter instanceof MessageFormatter && !$formatter instanceof MessageFormatterInterface) {
+ throw new \LogicException(\sprintf('Argument 2 to %s::log() must be of type %s', self::class, MessageFormatterInterface::class));
+ }
+ return static function (callable $handler) use($logger, $formatter, $logLevel) : callable {
+ return static function (RequestInterface $request, array $options = []) use($handler, $logger, $formatter, $logLevel) {
+ return $handler($request, $options)->then(static function ($response) use($logger, $request, $formatter, $logLevel) : ResponseInterface {
+ $message = $formatter->format($request, $response);
+ $logger->log($logLevel, $message);
+ return $response;
+ }, static function ($reason) use($logger, $request, $formatter) : PromiseInterface {
+ $response = $reason instanceof RequestException ? $reason->getResponse() : null;
+ $message = $formatter->format($request, $response, P\Create::exceptionFor($reason));
+ $logger->error($message);
+ return P\Create::rejectionFor($reason);
+ });
+ };
+ };
+ }
+ /**
+ * This middleware adds a default content-type if possible, a default
+ * content-length or transfer-encoding header, and the expect header.
+ */
+ public static function prepareBody() : callable
+ {
+ return static function (callable $handler) : PrepareBodyMiddleware {
+ return new PrepareBodyMiddleware($handler);
+ };
+ }
+ /**
+ * Middleware that applies a map function to the request before passing to
+ * the next handler.
+ *
+ * @param callable $fn Function that accepts a RequestInterface and returns
+ * a RequestInterface.
+ */
+ public static function mapRequest(callable $fn) : callable
+ {
+ return static function (callable $handler) use($fn) : callable {
+ return static function (RequestInterface $request, array $options) use($handler, $fn) {
+ return $handler($fn($request), $options);
+ };
+ };
+ }
+ /**
+ * Middleware that applies a map function to the resolved promise's
+ * response.
+ *
+ * @param callable $fn Function that accepts a ResponseInterface and
+ * returns a ResponseInterface.
+ */
+ public static function mapResponse(callable $fn) : callable
+ {
+ return static function (callable $handler) use($fn) : callable {
+ return static function (RequestInterface $request, array $options) use($handler, $fn) {
+ return $handler($request, $options)->then($fn);
+ };
+ };
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/Pool.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/Pool.php
new file mode 100755
index 00000000..f64c79ea
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/Pool.php
@@ -0,0 +1,116 @@
+ $rfn) {
+ if ($rfn instanceof RequestInterface) {
+ (yield $key => $client->sendAsync($rfn, $opts));
+ } elseif (\is_callable($rfn)) {
+ (yield $key => $rfn($opts));
+ } else {
+ throw new \InvalidArgumentException('Each value yielded by the iterator must be a Psr7\\Http\\Message\\RequestInterface or a callable that returns a promise that fulfills with a Psr7\\Message\\Http\\ResponseInterface object.');
+ }
+ }
+ };
+ $this->each = new EachPromise($requests(), $config);
+ }
+ /**
+ * Get promise
+ */
+ public function promise() : PromiseInterface
+ {
+ return $this->each->promise();
+ }
+ /**
+ * Sends multiple requests concurrently and returns an array of responses
+ * and exceptions that uses the same ordering as the provided requests.
+ *
+ * IMPORTANT: This method keeps every request and response in memory, and
+ * as such, is NOT recommended when sending a large number or an
+ * indeterminate number of requests concurrently.
+ *
+ * @param ClientInterface $client Client used to send the requests
+ * @param array|\Iterator $requests Requests to send concurrently.
+ * @param array $options Passes through the options available in
+ * {@see Pool::__construct}
+ *
+ * @return array Returns an array containing the response or an exception
+ * in the same order that the requests were sent.
+ *
+ * @throws \InvalidArgumentException if the event format is incorrect.
+ */
+ public static function batch(ClientInterface $client, $requests, array $options = []) : array
+ {
+ $res = [];
+ self::cmpCallback($options, 'fulfilled', $res);
+ self::cmpCallback($options, 'rejected', $res);
+ $pool = new static($client, $requests, $options);
+ $pool->promise()->wait();
+ \ksort($res);
+ return $res;
+ }
+ /**
+ * Execute callback(s)
+ */
+ private static function cmpCallback(array &$options, string $name, array &$results) : void
+ {
+ if (!isset($options[$name])) {
+ $options[$name] = static function ($v, $k) use(&$results) {
+ $results[$k] = $v;
+ };
+ } else {
+ $currentFn = $options[$name];
+ $options[$name] = static function ($v, $k) use(&$results, $currentFn) {
+ $currentFn($v, $k);
+ $results[$k] = $v;
+ };
+ }
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php
new file mode 100755
index 00000000..32dafdb5
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php
@@ -0,0 +1,86 @@
+nextHandler = $nextHandler;
+ }
+ public function __invoke(RequestInterface $request, array $options) : PromiseInterface
+ {
+ $fn = $this->nextHandler;
+ // Don't do anything if the request has no body.
+ if ($request->getBody()->getSize() === 0) {
+ return $fn($request, $options);
+ }
+ $modify = [];
+ // Add a default content-type if possible.
+ if (!$request->hasHeader('Content-Type')) {
+ if ($uri = $request->getBody()->getMetadata('uri')) {
+ if (\is_string($uri) && ($type = Psr7\MimeType::fromFilename($uri))) {
+ $modify['set_headers']['Content-Type'] = $type;
+ }
+ }
+ }
+ // Add a default content-length or transfer-encoding header.
+ if (!$request->hasHeader('Content-Length') && !$request->hasHeader('Transfer-Encoding')) {
+ $size = $request->getBody()->getSize();
+ if ($size !== null) {
+ $modify['set_headers']['Content-Length'] = $size;
+ } else {
+ $modify['set_headers']['Transfer-Encoding'] = 'chunked';
+ }
+ }
+ // Add the expect header if needed.
+ $this->addExpectHeader($request, $options, $modify);
+ return $fn(Psr7\Utils::modifyRequest($request, $modify), $options);
+ }
+ /**
+ * Add expect header
+ */
+ private function addExpectHeader(RequestInterface $request, array $options, array &$modify) : void
+ {
+ // Determine if the Expect header should be used
+ if ($request->hasHeader('Expect')) {
+ return;
+ }
+ $expect = $options['expect'] ?? null;
+ // Return if disabled or using HTTP/1.0
+ if ($expect === \false || $request->getProtocolVersion() === '1.0') {
+ return;
+ }
+ // The expect header is unconditionally enabled
+ if ($expect === \true) {
+ $modify['set_headers']['Expect'] = '100-Continue';
+ return;
+ }
+ // By default, send the expect header when the payload is > 1mb
+ if ($expect === null) {
+ $expect = 1048576;
+ }
+ // Always add if the body cannot be rewound, the size cannot be
+ // determined, or the size is greater than the cutoff threshold
+ $body = $request->getBody();
+ $size = $body->getSize();
+ if ($size === null || $size >= (int) $expect || !$body->isSeekable()) {
+ $modify['set_headers']['Expect'] = '100-Continue';
+ }
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/RedirectMiddleware.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/RedirectMiddleware.php
new file mode 100755
index 00000000..fffc9912
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/RedirectMiddleware.php
@@ -0,0 +1,162 @@
+ 5, 'protocols' => ['http', 'https'], 'strict' => \false, 'referer' => \false, 'track_redirects' => \false];
+ /**
+ * @var callable(RequestInterface, array): PromiseInterface
+ */
+ private $nextHandler;
+ /**
+ * @param callable(RequestInterface, array): PromiseInterface $nextHandler Next handler to invoke.
+ */
+ public function __construct(callable $nextHandler)
+ {
+ $this->nextHandler = $nextHandler;
+ }
+ public function __invoke(RequestInterface $request, array $options) : PromiseInterface
+ {
+ $fn = $this->nextHandler;
+ if (empty($options['allow_redirects'])) {
+ return $fn($request, $options);
+ }
+ if ($options['allow_redirects'] === \true) {
+ $options['allow_redirects'] = self::$defaultSettings;
+ } elseif (!\is_array($options['allow_redirects'])) {
+ throw new \InvalidArgumentException('allow_redirects must be true, false, or array');
+ } else {
+ // Merge the default settings with the provided settings
+ $options['allow_redirects'] += self::$defaultSettings;
+ }
+ if (empty($options['allow_redirects']['max'])) {
+ return $fn($request, $options);
+ }
+ return $fn($request, $options)->then(function (ResponseInterface $response) use($request, $options) {
+ return $this->checkRedirect($request, $options, $response);
+ });
+ }
+ /**
+ * @return ResponseInterface|PromiseInterface
+ */
+ public function checkRedirect(RequestInterface $request, array $options, ResponseInterface $response)
+ {
+ if (\strpos((string) $response->getStatusCode(), '3') !== 0 || !$response->hasHeader('Location')) {
+ return $response;
+ }
+ $this->guardMax($request, $response, $options);
+ $nextRequest = $this->modifyRequest($request, $options, $response);
+ // If authorization is handled by curl, unset it if URI is cross-origin.
+ if (Psr7\UriComparator::isCrossOrigin($request->getUri(), $nextRequest->getUri()) && \defined('\\CURLOPT_HTTPAUTH')) {
+ unset($options['curl'][\CURLOPT_HTTPAUTH], $options['curl'][\CURLOPT_USERPWD]);
+ }
+ if (isset($options['allow_redirects']['on_redirect'])) {
+ $options['allow_redirects']['on_redirect']($request, $response, $nextRequest->getUri());
+ }
+ $promise = $this($nextRequest, $options);
+ // Add headers to be able to track history of redirects.
+ if (!empty($options['allow_redirects']['track_redirects'])) {
+ return $this->withTracking($promise, (string) $nextRequest->getUri(), $response->getStatusCode());
+ }
+ return $promise;
+ }
+ /**
+ * Enable tracking on promise.
+ */
+ private function withTracking(PromiseInterface $promise, string $uri, int $statusCode) : PromiseInterface
+ {
+ return $promise->then(static function (ResponseInterface $response) use($uri, $statusCode) {
+ // Note that we are pushing to the front of the list as this
+ // would be an earlier response than what is currently present
+ // in the history header.
+ $historyHeader = $response->getHeader(self::HISTORY_HEADER);
+ $statusHeader = $response->getHeader(self::STATUS_HISTORY_HEADER);
+ \array_unshift($historyHeader, $uri);
+ \array_unshift($statusHeader, (string) $statusCode);
+ return $response->withHeader(self::HISTORY_HEADER, $historyHeader)->withHeader(self::STATUS_HISTORY_HEADER, $statusHeader);
+ });
+ }
+ /**
+ * Check for too many redirects.
+ *
+ * @throws TooManyRedirectsException Too many redirects.
+ */
+ private function guardMax(RequestInterface $request, ResponseInterface $response, array &$options) : void
+ {
+ $current = $options['__redirect_count'] ?? 0;
+ $options['__redirect_count'] = $current + 1;
+ $max = $options['allow_redirects']['max'];
+ if ($options['__redirect_count'] > $max) {
+ throw new TooManyRedirectsException("Will not follow more than {$max} redirects", $request, $response);
+ }
+ }
+ public function modifyRequest(RequestInterface $request, array $options, ResponseInterface $response) : RequestInterface
+ {
+ // Request modifications to apply.
+ $modify = [];
+ $protocols = $options['allow_redirects']['protocols'];
+ // Use a GET request if this is an entity enclosing request and we are
+ // not forcing RFC compliance, but rather emulating what all browsers
+ // would do.
+ $statusCode = $response->getStatusCode();
+ if ($statusCode == 303 || $statusCode <= 302 && !$options['allow_redirects']['strict']) {
+ $safeMethods = ['GET', 'HEAD', 'OPTIONS'];
+ $requestMethod = $request->getMethod();
+ $modify['method'] = \in_array($requestMethod, $safeMethods) ? $requestMethod : 'GET';
+ $modify['body'] = '';
+ }
+ $uri = self::redirectUri($request, $response, $protocols);
+ if (isset($options['idn_conversion']) && $options['idn_conversion'] !== \false) {
+ $idnOptions = $options['idn_conversion'] === \true ? \IDNA_DEFAULT : $options['idn_conversion'];
+ $uri = Utils::idnUriConvert($uri, $idnOptions);
+ }
+ $modify['uri'] = $uri;
+ Psr7\Message::rewindBody($request);
+ // Add the Referer header if it is told to do so and only
+ // add the header if we are not redirecting from https to http.
+ if ($options['allow_redirects']['referer'] && $modify['uri']->getScheme() === $request->getUri()->getScheme()) {
+ $uri = $request->getUri()->withUserInfo('');
+ $modify['set_headers']['Referer'] = (string) $uri;
+ } else {
+ $modify['remove_headers'][] = 'Referer';
+ }
+ // Remove Authorization and Cookie headers if URI is cross-origin.
+ if (Psr7\UriComparator::isCrossOrigin($request->getUri(), $modify['uri'])) {
+ $modify['remove_headers'][] = 'Authorization';
+ $modify['remove_headers'][] = 'Cookie';
+ }
+ return Psr7\Utils::modifyRequest($request, $modify);
+ }
+ /**
+ * Set the appropriate URL on the request based on the location header.
+ */
+ private static function redirectUri(RequestInterface $request, ResponseInterface $response, array $protocols) : UriInterface
+ {
+ $location = Psr7\UriResolver::resolve($request->getUri(), new Psr7\Uri($response->getHeaderLine('Location')));
+ // Ensure that the redirect URI is allowed based on the protocols.
+ if (!\in_array($location->getScheme(), $protocols)) {
+ throw new BadResponseException(\sprintf('Redirect URI, %s, does not use one of the allowed redirect protocols: %s', $location, \implode(', ', $protocols)), $request, $response);
+ }
+ return $location;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/RequestOptions.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/RequestOptions.php
new file mode 100755
index 00000000..9dccb919
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/RequestOptions.php
@@ -0,0 +1,244 @@
+decider = $decider;
+ $this->nextHandler = $nextHandler;
+ $this->delay = $delay ?: __CLASS__ . '::exponentialDelay';
+ }
+ /**
+ * Default exponential backoff delay function.
+ *
+ * @return int milliseconds.
+ */
+ public static function exponentialDelay(int $retries) : int
+ {
+ return (int) 2 ** ($retries - 1) * 1000;
+ }
+ public function __invoke(RequestInterface $request, array $options) : PromiseInterface
+ {
+ if (!isset($options['retries'])) {
+ $options['retries'] = 0;
+ }
+ $fn = $this->nextHandler;
+ return $fn($request, $options)->then($this->onFulfilled($request, $options), $this->onRejected($request, $options));
+ }
+ /**
+ * Execute fulfilled closure
+ */
+ private function onFulfilled(RequestInterface $request, array $options) : callable
+ {
+ return function ($value) use($request, $options) {
+ if (!($this->decider)($options['retries'], $request, $value, null)) {
+ return $value;
+ }
+ return $this->doRetry($request, $options, $value);
+ };
+ }
+ /**
+ * Execute rejected closure
+ */
+ private function onRejected(RequestInterface $req, array $options) : callable
+ {
+ return function ($reason) use($req, $options) {
+ if (!($this->decider)($options['retries'], $req, null, $reason)) {
+ return P\Create::rejectionFor($reason);
+ }
+ return $this->doRetry($req, $options);
+ };
+ }
+ private function doRetry(RequestInterface $request, array $options, ?ResponseInterface $response = null) : PromiseInterface
+ {
+ $options['delay'] = ($this->delay)(++$options['retries'], $response, $request);
+ return $this($request, $options);
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/TransferStats.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/TransferStats.php
new file mode 100755
index 00000000..e1eca7a3
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/TransferStats.php
@@ -0,0 +1,114 @@
+request = $request;
+ $this->response = $response;
+ $this->transferTime = $transferTime;
+ $this->handlerErrorData = $handlerErrorData;
+ $this->handlerStats = $handlerStats;
+ }
+ public function getRequest() : RequestInterface
+ {
+ return $this->request;
+ }
+ /**
+ * Returns the response that was received (if any).
+ */
+ public function getResponse() : ?ResponseInterface
+ {
+ return $this->response;
+ }
+ /**
+ * Returns true if a response was received.
+ */
+ public function hasResponse() : bool
+ {
+ return $this->response !== null;
+ }
+ /**
+ * Gets handler specific error data.
+ *
+ * This might be an exception, a integer representing an error code, or
+ * anything else. Relying on this value assumes that you know what handler
+ * you are using.
+ *
+ * @return mixed
+ */
+ public function getHandlerErrorData()
+ {
+ return $this->handlerErrorData;
+ }
+ /**
+ * Get the effective URI the request was sent to.
+ */
+ public function getEffectiveUri() : UriInterface
+ {
+ return $this->request->getUri();
+ }
+ /**
+ * Get the estimated time the request was being transferred by the handler.
+ *
+ * @return float|null Time in seconds.
+ */
+ public function getTransferTime() : ?float
+ {
+ return $this->transferTime;
+ }
+ /**
+ * Gets an array of all of the handler specific transfer data.
+ */
+ public function getHandlerStats() : array
+ {
+ return $this->handlerStats;
+ }
+ /**
+ * Get a specific handler statistic from the handler by name.
+ *
+ * @param string $stat Handler specific transfer stat to retrieve.
+ *
+ * @return mixed|null
+ */
+ public function getHandlerStat(string $stat)
+ {
+ return $this->handlerStats[$stat] ?? null;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/Utils.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/Utils.php
new file mode 100755
index 00000000..545e83bf
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/Utils.php
@@ -0,0 +1,339 @@
+= 0) {
+ if (\function_exists('curl_multi_exec') && \function_exists('curl_exec')) {
+ $handler = Proxy::wrapSync(new CurlMultiHandler(), new CurlHandler());
+ } elseif (\function_exists('curl_exec')) {
+ $handler = new CurlHandler();
+ } elseif (\function_exists('curl_multi_exec')) {
+ $handler = new CurlMultiHandler();
+ }
+ }
+ if (\ini_get('allow_url_fopen')) {
+ $handler = $handler ? Proxy::wrapStreaming($handler, new StreamHandler()) : new StreamHandler();
+ } elseif (!$handler) {
+ throw new \RuntimeException('GuzzleHttp requires cURL, the allow_url_fopen ini setting, or a custom HTTP handler.');
+ }
+ return $handler;
+ }
+ /**
+ * Get the default User-Agent string to use with Guzzle.
+ */
+ public static function defaultUserAgent() : string
+ {
+ return \sprintf('GuzzleHttp/%d', ClientInterface::MAJOR_VERSION);
+ }
+ /**
+ * Returns the default cacert bundle for the current system.
+ *
+ * First, the openssl.cafile and curl.cainfo php.ini settings are checked.
+ * If those settings are not configured, then the common locations for
+ * bundles found on Red Hat, CentOS, Fedora, Ubuntu, Debian, FreeBSD, OS X
+ * and Windows are checked. If any of these file locations are found on
+ * disk, they will be utilized.
+ *
+ * Note: the result of this function is cached for subsequent calls.
+ *
+ * @throws \RuntimeException if no bundle can be found.
+ *
+ * @deprecated Utils::defaultCaBundle will be removed in guzzlehttp/guzzle:8.0. This method is not needed in PHP 5.6+.
+ */
+ public static function defaultCaBundle() : string
+ {
+ static $cached = null;
+ static $cafiles = [
+ // Red Hat, CentOS, Fedora (provided by the ca-certificates package)
+ '/etc/pki/tls/certs/ca-bundle.crt',
+ // Ubuntu, Debian (provided by the ca-certificates package)
+ '/etc/ssl/certs/ca-certificates.crt',
+ // FreeBSD (provided by the ca_root_nss package)
+ '/usr/local/share/certs/ca-root-nss.crt',
+ // SLES 12 (provided by the ca-certificates package)
+ '/var/lib/ca-certificates/ca-bundle.pem',
+ // OS X provided by homebrew (using the default path)
+ '/usr/local/etc/openssl/cert.pem',
+ // Google app engine
+ '/etc/ca-certificates.crt',
+ // Windows?
+ 'C:\\windows\\system32\\curl-ca-bundle.crt',
+ 'C:\\windows\\curl-ca-bundle.crt',
+ ];
+ if ($cached) {
+ return $cached;
+ }
+ if ($ca = \ini_get('openssl.cafile')) {
+ return $cached = $ca;
+ }
+ if ($ca = \ini_get('curl.cainfo')) {
+ return $cached = $ca;
+ }
+ foreach ($cafiles as $filename) {
+ if (\file_exists($filename)) {
+ return $cached = $filename;
+ }
+ }
+ throw new \RuntimeException(<<getHost()) {
+ $asciiHost = self::idnToAsci($uri->getHost(), $options, $info);
+ if ($asciiHost === \false) {
+ $errorBitSet = $info['errors'] ?? 0;
+ $errorConstants = \array_filter(\array_keys(\get_defined_constants()), static function (string $name) : bool {
+ return \substr($name, 0, 11) === 'IDNA_ERROR_';
+ });
+ $errors = [];
+ foreach ($errorConstants as $errorConstant) {
+ if ($errorBitSet & \constant($errorConstant)) {
+ $errors[] = $errorConstant;
+ }
+ }
+ $errorMessage = 'IDN conversion failed';
+ if ($errors) {
+ $errorMessage .= ' (errors: ' . \implode(', ', $errors) . ')';
+ }
+ throw new InvalidArgumentException($errorMessage);
+ }
+ if ($uri->getHost() !== $asciiHost) {
+ // Replace URI only if the ASCII version is different
+ $uri = $uri->withHost($asciiHost);
+ }
+ }
+ return $uri;
+ }
+ /**
+ * @internal
+ */
+ public static function getenv(string $name) : ?string
+ {
+ if (isset($_SERVER[$name])) {
+ return (string) $_SERVER[$name];
+ }
+ if (\PHP_SAPI === 'cli' && ($value = \getenv($name)) !== \false && $value !== null) {
+ return (string) $value;
+ }
+ return null;
+ }
+ /**
+ * @return string|false
+ */
+ private static function idnToAsci(string $domain, int $options, ?array &$info = [])
+ {
+ if (\function_exists('idn_to_ascii') && \defined('INTL_IDNA_VARIANT_UTS46')) {
+ return \idn_to_ascii($domain, $options, \INTL_IDNA_VARIANT_UTS46, $info);
+ }
+ throw new \Error('ext-idn or symfony/polyfill-intl-idn not loaded or too old');
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/functions.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/functions.php
new file mode 100755
index 00000000..6e1def71
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/guzzle/src/functions.php
@@ -0,0 +1,158 @@
+
+Copyright (c) 2015 Graham Campbell
+Copyright (c) 2017 Tobias Schultze
+Copyright (c) 2020 Tobias Nyholm
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/promises/src/AggregateException.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/promises/src/AggregateException.php
new file mode 100755
index 00000000..0d0770c8
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/promises/src/AggregateException.php
@@ -0,0 +1,15 @@
+then(function ($v) { echo $v; });
+ *
+ * @param callable $generatorFn Generator function to wrap into a promise.
+ *
+ * @return Promise
+ *
+ * @see https://github.com/petkaantonov/bluebird/blob/master/API.md#generators inspiration
+ */
+final class Coroutine implements PromiseInterface
+{
+ /**
+ * @var PromiseInterface|null
+ */
+ private $currentPromise;
+ /**
+ * @var Generator
+ */
+ private $generator;
+ /**
+ * @var Promise
+ */
+ private $result;
+ public function __construct(callable $generatorFn)
+ {
+ $this->generator = $generatorFn();
+ $this->result = new Promise(function () : void {
+ while (isset($this->currentPromise)) {
+ $this->currentPromise->wait();
+ }
+ });
+ try {
+ $this->nextCoroutine($this->generator->current());
+ } catch (Throwable $throwable) {
+ $this->result->reject($throwable);
+ }
+ }
+ /**
+ * Create a new coroutine.
+ */
+ public static function of(callable $generatorFn) : self
+ {
+ return new self($generatorFn);
+ }
+ public function then(?callable $onFulfilled = null, ?callable $onRejected = null) : PromiseInterface
+ {
+ return $this->result->then($onFulfilled, $onRejected);
+ }
+ public function otherwise(callable $onRejected) : PromiseInterface
+ {
+ return $this->result->otherwise($onRejected);
+ }
+ public function wait(bool $unwrap = \true)
+ {
+ return $this->result->wait($unwrap);
+ }
+ public function getState() : string
+ {
+ return $this->result->getState();
+ }
+ public function resolve($value) : void
+ {
+ $this->result->resolve($value);
+ }
+ public function reject($reason) : void
+ {
+ $this->result->reject($reason);
+ }
+ public function cancel() : void
+ {
+ $this->currentPromise->cancel();
+ $this->result->cancel();
+ }
+ private function nextCoroutine($yielded) : void
+ {
+ $this->currentPromise = Create::promiseFor($yielded)->then([$this, '_handleSuccess'], [$this, '_handleFailure']);
+ }
+ /**
+ * @internal
+ */
+ public function _handleSuccess($value) : void
+ {
+ unset($this->currentPromise);
+ try {
+ $next = $this->generator->send($value);
+ if ($this->generator->valid()) {
+ $this->nextCoroutine($next);
+ } else {
+ $this->result->resolve($value);
+ }
+ } catch (Throwable $throwable) {
+ $this->result->reject($throwable);
+ }
+ }
+ /**
+ * @internal
+ */
+ public function _handleFailure($reason) : void
+ {
+ unset($this->currentPromise);
+ try {
+ $nextYield = $this->generator->throw(Create::exceptionFor($reason));
+ // The throw was caught, so keep iterating on the coroutine
+ $this->nextCoroutine($nextYield);
+ } catch (Throwable $throwable) {
+ $this->result->reject($throwable);
+ }
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/promises/src/Create.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/promises/src/Create.php
new file mode 100755
index 00000000..8421dcdc
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/promises/src/Create.php
@@ -0,0 +1,68 @@
+then([$promise, 'resolve'], [$promise, 'reject']);
+ return $promise;
+ }
+ return new FulfilledPromise($value);
+ }
+ /**
+ * Creates a rejected promise for a reason if the reason is not a promise.
+ * If the provided reason is a promise, then it is returned as-is.
+ *
+ * @param mixed $reason Promise or reason.
+ */
+ public static function rejectionFor($reason) : PromiseInterface
+ {
+ if ($reason instanceof PromiseInterface) {
+ return $reason;
+ }
+ return new RejectedPromise($reason);
+ }
+ /**
+ * Create an exception for a rejected promise value.
+ *
+ * @param mixed $reason
+ */
+ public static function exceptionFor($reason) : \Throwable
+ {
+ if ($reason instanceof \Throwable) {
+ return $reason;
+ }
+ return new RejectionException($reason);
+ }
+ /**
+ * Returns an iterator for the given value.
+ *
+ * @param mixed $value
+ */
+ public static function iterFor($value) : \Iterator
+ {
+ if ($value instanceof \Iterator) {
+ return $value;
+ }
+ if (\is_array($value)) {
+ return new \ArrayIterator($value);
+ }
+ return new \ArrayIterator([$value]);
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/promises/src/Each.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/promises/src/Each.php
new file mode 100755
index 00000000..09aeaa73
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/promises/src/Each.php
@@ -0,0 +1,56 @@
+ $onFulfilled, 'rejected' => $onRejected]))->promise();
+ }
+ /**
+ * Like of, but only allows a certain number of outstanding promises at any
+ * given time.
+ *
+ * $concurrency may be an integer or a function that accepts the number of
+ * pending promises and returns a numeric concurrency limit value to allow
+ * for dynamic a concurrency size.
+ *
+ * @param mixed $iterable
+ * @param int|callable $concurrency
+ */
+ public static function ofLimit($iterable, $concurrency, ?callable $onFulfilled = null, ?callable $onRejected = null) : PromiseInterface
+ {
+ return (new EachPromise($iterable, ['fulfilled' => $onFulfilled, 'rejected' => $onRejected, 'concurrency' => $concurrency]))->promise();
+ }
+ /**
+ * Like limit, but ensures that no promise in the given $iterable argument
+ * is rejected. If any promise is rejected, then the aggregate promise is
+ * rejected with the encountered rejection.
+ *
+ * @param mixed $iterable
+ * @param int|callable $concurrency
+ */
+ public static function ofLimitAll($iterable, $concurrency, ?callable $onFulfilled = null) : PromiseInterface
+ {
+ return self::ofLimit($iterable, $concurrency, $onFulfilled, function ($reason, $idx, PromiseInterface $aggregate) : void {
+ $aggregate->reject($reason);
+ });
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/promises/src/EachPromise.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/promises/src/EachPromise.php
new file mode 100755
index 00000000..d85f8cde
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/promises/src/EachPromise.php
@@ -0,0 +1,196 @@
+iterable = Create::iterFor($iterable);
+ if (isset($config['concurrency'])) {
+ $this->concurrency = $config['concurrency'];
+ }
+ if (isset($config['fulfilled'])) {
+ $this->onFulfilled = $config['fulfilled'];
+ }
+ if (isset($config['rejected'])) {
+ $this->onRejected = $config['rejected'];
+ }
+ }
+ /** @psalm-suppress InvalidNullableReturnType */
+ public function promise() : PromiseInterface
+ {
+ if ($this->aggregate) {
+ return $this->aggregate;
+ }
+ try {
+ $this->createPromise();
+ /** @psalm-assert Promise $this->aggregate */
+ $this->iterable->rewind();
+ $this->refillPending();
+ } catch (\Throwable $e) {
+ $this->aggregate->reject($e);
+ }
+ /**
+ * @psalm-suppress NullableReturnStatement
+ */
+ return $this->aggregate;
+ }
+ private function createPromise() : void
+ {
+ $this->mutex = \false;
+ $this->aggregate = new Promise(function () : void {
+ if ($this->checkIfFinished()) {
+ return;
+ }
+ \reset($this->pending);
+ // Consume a potentially fluctuating list of promises while
+ // ensuring that indexes are maintained (precluding array_shift).
+ while ($promise = \current($this->pending)) {
+ \next($this->pending);
+ $promise->wait();
+ if (Is::settled($this->aggregate)) {
+ return;
+ }
+ }
+ });
+ // Clear the references when the promise is resolved.
+ $clearFn = function () : void {
+ $this->iterable = $this->concurrency = $this->pending = null;
+ $this->onFulfilled = $this->onRejected = null;
+ $this->nextPendingIndex = 0;
+ };
+ $this->aggregate->then($clearFn, $clearFn);
+ }
+ private function refillPending() : void
+ {
+ if (!$this->concurrency) {
+ // Add all pending promises.
+ while ($this->addPending() && $this->advanceIterator()) {
+ }
+ return;
+ }
+ // Add only up to N pending promises.
+ $concurrency = \is_callable($this->concurrency) ? ($this->concurrency)(\count($this->pending)) : $this->concurrency;
+ $concurrency = \max($concurrency - \count($this->pending), 0);
+ // Concurrency may be set to 0 to disallow new promises.
+ if (!$concurrency) {
+ return;
+ }
+ // Add the first pending promise.
+ $this->addPending();
+ // Note this is special handling for concurrency=1 so that we do
+ // not advance the iterator after adding the first promise. This
+ // helps work around issues with generators that might not have the
+ // next value to yield until promise callbacks are called.
+ while (--$concurrency && $this->advanceIterator() && $this->addPending()) {
+ }
+ }
+ private function addPending() : bool
+ {
+ if (!$this->iterable || !$this->iterable->valid()) {
+ return \false;
+ }
+ $promise = Create::promiseFor($this->iterable->current());
+ $key = $this->iterable->key();
+ // Iterable keys may not be unique, so we use a counter to
+ // guarantee uniqueness
+ $idx = $this->nextPendingIndex++;
+ $this->pending[$idx] = $promise->then(function ($value) use($idx, $key) : void {
+ if ($this->onFulfilled) {
+ ($this->onFulfilled)($value, $key, $this->aggregate);
+ }
+ $this->step($idx);
+ }, function ($reason) use($idx, $key) : void {
+ if ($this->onRejected) {
+ ($this->onRejected)($reason, $key, $this->aggregate);
+ }
+ $this->step($idx);
+ });
+ return \true;
+ }
+ private function advanceIterator() : bool
+ {
+ // Place a lock on the iterator so that we ensure to not recurse,
+ // preventing fatal generator errors.
+ if ($this->mutex) {
+ return \false;
+ }
+ $this->mutex = \true;
+ try {
+ $this->iterable->next();
+ $this->mutex = \false;
+ return \true;
+ } catch (\Throwable $e) {
+ $this->aggregate->reject($e);
+ $this->mutex = \false;
+ return \false;
+ }
+ }
+ private function step(int $idx) : void
+ {
+ // If the promise was already resolved, then ignore this step.
+ if (Is::settled($this->aggregate)) {
+ return;
+ }
+ unset($this->pending[$idx]);
+ // Only refill pending promises if we are not locked, preventing the
+ // EachPromise to recursively invoke the provided iterator, which
+ // cause a fatal error: "Cannot resume an already running generator"
+ if ($this->advanceIterator() && !$this->checkIfFinished()) {
+ // Add more pending promises if possible.
+ $this->refillPending();
+ }
+ }
+ private function checkIfFinished() : bool
+ {
+ if (!$this->pending && !$this->iterable->valid()) {
+ // Resolve the promise if there's nothing left to do.
+ $this->aggregate->resolve(null);
+ return \true;
+ }
+ return \false;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/promises/src/FulfilledPromise.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/promises/src/FulfilledPromise.php
new file mode 100755
index 00000000..7cf85af3
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/promises/src/FulfilledPromise.php
@@ -0,0 +1,73 @@
+value = $value;
+ }
+ public function then(?callable $onFulfilled = null, ?callable $onRejected = null) : PromiseInterface
+ {
+ // Return itself if there is no onFulfilled function.
+ if (!$onFulfilled) {
+ return $this;
+ }
+ $queue = Utils::queue();
+ $p = new Promise([$queue, 'run']);
+ $value = $this->value;
+ $queue->add(static function () use($p, $value, $onFulfilled) : void {
+ if (Is::pending($p)) {
+ try {
+ $p->resolve($onFulfilled($value));
+ } catch (\Throwable $e) {
+ $p->reject($e);
+ }
+ }
+ });
+ return $p;
+ }
+ public function otherwise(callable $onRejected) : PromiseInterface
+ {
+ return $this->then(null, $onRejected);
+ }
+ public function wait(bool $unwrap = \true)
+ {
+ return $unwrap ? $this->value : null;
+ }
+ public function getState() : string
+ {
+ return self::FULFILLED;
+ }
+ public function resolve($value) : void
+ {
+ if ($value !== $this->value) {
+ throw new \LogicException('Cannot resolve a fulfilled promise');
+ }
+ }
+ public function reject($reason) : void
+ {
+ throw new \LogicException('Cannot reject a fulfilled promise');
+ }
+ public function cancel() : void
+ {
+ // pass
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/promises/src/Is.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/promises/src/Is.php
new file mode 100755
index 00000000..c086a9a7
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/promises/src/Is.php
@@ -0,0 +1,36 @@
+getState() === PromiseInterface::PENDING;
+ }
+ /**
+ * Returns true if a promise is fulfilled or rejected.
+ */
+ public static function settled(PromiseInterface $promise) : bool
+ {
+ return $promise->getState() !== PromiseInterface::PENDING;
+ }
+ /**
+ * Returns true if a promise is fulfilled.
+ */
+ public static function fulfilled(PromiseInterface $promise) : bool
+ {
+ return $promise->getState() === PromiseInterface::FULFILLED;
+ }
+ /**
+ * Returns true if a promise is rejected.
+ */
+ public static function rejected(PromiseInterface $promise) : bool
+ {
+ return $promise->getState() === PromiseInterface::REJECTED;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/promises/src/Promise.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/promises/src/Promise.php
new file mode 100755
index 00000000..f090ead0
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/promises/src/Promise.php
@@ -0,0 +1,236 @@
+waitFn = $waitFn;
+ $this->cancelFn = $cancelFn;
+ }
+ public function then(?callable $onFulfilled = null, ?callable $onRejected = null) : PromiseInterface
+ {
+ if ($this->state === self::PENDING) {
+ $p = new Promise(null, [$this, 'cancel']);
+ $this->handlers[] = [$p, $onFulfilled, $onRejected];
+ $p->waitList = $this->waitList;
+ $p->waitList[] = $this;
+ return $p;
+ }
+ // Return a fulfilled promise and immediately invoke any callbacks.
+ if ($this->state === self::FULFILLED) {
+ $promise = Create::promiseFor($this->result);
+ return $onFulfilled ? $promise->then($onFulfilled) : $promise;
+ }
+ // It's either cancelled or rejected, so return a rejected promise
+ // and immediately invoke any callbacks.
+ $rejection = Create::rejectionFor($this->result);
+ return $onRejected ? $rejection->then(null, $onRejected) : $rejection;
+ }
+ public function otherwise(callable $onRejected) : PromiseInterface
+ {
+ return $this->then(null, $onRejected);
+ }
+ public function wait(bool $unwrap = \true)
+ {
+ $this->waitIfPending();
+ if ($this->result instanceof PromiseInterface) {
+ return $this->result->wait($unwrap);
+ }
+ if ($unwrap) {
+ if ($this->state === self::FULFILLED) {
+ return $this->result;
+ }
+ // It's rejected so "unwrap" and throw an exception.
+ throw Create::exceptionFor($this->result);
+ }
+ }
+ public function getState() : string
+ {
+ return $this->state;
+ }
+ public function cancel() : void
+ {
+ if ($this->state !== self::PENDING) {
+ return;
+ }
+ $this->waitFn = $this->waitList = null;
+ if ($this->cancelFn) {
+ $fn = $this->cancelFn;
+ $this->cancelFn = null;
+ try {
+ $fn();
+ } catch (\Throwable $e) {
+ $this->reject($e);
+ }
+ }
+ // Reject the promise only if it wasn't rejected in a then callback.
+ /** @psalm-suppress RedundantCondition */
+ if ($this->state === self::PENDING) {
+ $this->reject(new CancellationException('Promise has been cancelled'));
+ }
+ }
+ public function resolve($value) : void
+ {
+ $this->settle(self::FULFILLED, $value);
+ }
+ public function reject($reason) : void
+ {
+ $this->settle(self::REJECTED, $reason);
+ }
+ private function settle(string $state, $value) : void
+ {
+ if ($this->state !== self::PENDING) {
+ // Ignore calls with the same resolution.
+ if ($state === $this->state && $value === $this->result) {
+ return;
+ }
+ throw $this->state === $state ? new \LogicException("The promise is already {$state}.") : new \LogicException("Cannot change a {$this->state} promise to {$state}");
+ }
+ if ($value === $this) {
+ throw new \LogicException('Cannot fulfill or reject a promise with itself');
+ }
+ // Clear out the state of the promise but stash the handlers.
+ $this->state = $state;
+ $this->result = $value;
+ $handlers = $this->handlers;
+ $this->handlers = null;
+ $this->waitList = $this->waitFn = null;
+ $this->cancelFn = null;
+ if (!$handlers) {
+ return;
+ }
+ // If the value was not a settled promise or a thenable, then resolve
+ // it in the task queue using the correct ID.
+ if (!\is_object($value) || !\method_exists($value, 'then')) {
+ $id = $state === self::FULFILLED ? 1 : 2;
+ // It's a success, so resolve the handlers in the queue.
+ Utils::queue()->add(static function () use($id, $value, $handlers) : void {
+ foreach ($handlers as $handler) {
+ self::callHandler($id, $value, $handler);
+ }
+ });
+ } elseif ($value instanceof Promise && Is::pending($value)) {
+ // We can just merge our handlers onto the next promise.
+ $value->handlers = \array_merge($value->handlers, $handlers);
+ } else {
+ // Resolve the handlers when the forwarded promise is resolved.
+ $value->then(static function ($value) use($handlers) : void {
+ foreach ($handlers as $handler) {
+ self::callHandler(1, $value, $handler);
+ }
+ }, static function ($reason) use($handlers) : void {
+ foreach ($handlers as $handler) {
+ self::callHandler(2, $reason, $handler);
+ }
+ });
+ }
+ }
+ /**
+ * Call a stack of handlers using a specific callback index and value.
+ *
+ * @param int $index 1 (resolve) or 2 (reject).
+ * @param mixed $value Value to pass to the callback.
+ * @param array $handler Array of handler data (promise and callbacks).
+ */
+ private static function callHandler(int $index, $value, array $handler) : void
+ {
+ /** @var PromiseInterface $promise */
+ $promise = $handler[0];
+ // The promise may have been cancelled or resolved before placing
+ // this thunk in the queue.
+ if (Is::settled($promise)) {
+ return;
+ }
+ try {
+ if (isset($handler[$index])) {
+ /*
+ * If $f throws an exception, then $handler will be in the exception
+ * stack trace. Since $handler contains a reference to the callable
+ * itself we get a circular reference. We clear the $handler
+ * here to avoid that memory leak.
+ */
+ $f = $handler[$index];
+ unset($handler);
+ $promise->resolve($f($value));
+ } elseif ($index === 1) {
+ // Forward resolution values as-is.
+ $promise->resolve($value);
+ } else {
+ // Forward rejections down the chain.
+ $promise->reject($value);
+ }
+ } catch (\Throwable $reason) {
+ $promise->reject($reason);
+ }
+ }
+ private function waitIfPending() : void
+ {
+ if ($this->state !== self::PENDING) {
+ return;
+ } elseif ($this->waitFn) {
+ $this->invokeWaitFn();
+ } elseif ($this->waitList) {
+ $this->invokeWaitList();
+ } else {
+ // If there's no wait function, then reject the promise.
+ $this->reject('Cannot wait on a promise that has ' . 'no internal wait function. You must provide a wait ' . 'function when constructing the promise to be able to ' . 'wait on a promise.');
+ }
+ Utils::queue()->run();
+ /** @psalm-suppress RedundantCondition */
+ if ($this->state === self::PENDING) {
+ $this->reject('Invoking the wait callback did not resolve the promise');
+ }
+ }
+ private function invokeWaitFn() : void
+ {
+ try {
+ $wfn = $this->waitFn;
+ $this->waitFn = null;
+ $wfn(\true);
+ } catch (\Throwable $reason) {
+ if ($this->state === self::PENDING) {
+ // The promise has not been resolved yet, so reject the promise
+ // with the exception.
+ $this->reject($reason);
+ } else {
+ // The promise was already resolved, so there's a problem in
+ // the application.
+ throw $reason;
+ }
+ }
+ }
+ private function invokeWaitList() : void
+ {
+ $waitList = $this->waitList;
+ $this->waitList = null;
+ foreach ($waitList as $result) {
+ do {
+ $result->waitIfPending();
+ $result = $result->result;
+ } while ($result instanceof Promise);
+ if ($result instanceof PromiseInterface) {
+ $result->wait(\false);
+ }
+ }
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/promises/src/PromiseInterface.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/promises/src/PromiseInterface.php
new file mode 100755
index 00000000..f06df42a
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/promises/src/PromiseInterface.php
@@ -0,0 +1,80 @@
+reason = $reason;
+ }
+ public function then(?callable $onFulfilled = null, ?callable $onRejected = null) : PromiseInterface
+ {
+ // If there's no onRejected callback then just return self.
+ if (!$onRejected) {
+ return $this;
+ }
+ $queue = Utils::queue();
+ $reason = $this->reason;
+ $p = new Promise([$queue, 'run']);
+ $queue->add(static function () use($p, $reason, $onRejected) : void {
+ if (Is::pending($p)) {
+ try {
+ // Return a resolved promise if onRejected does not throw.
+ $p->resolve($onRejected($reason));
+ } catch (\Throwable $e) {
+ // onRejected threw, so return a rejected promise.
+ $p->reject($e);
+ }
+ }
+ });
+ return $p;
+ }
+ public function otherwise(callable $onRejected) : PromiseInterface
+ {
+ return $this->then(null, $onRejected);
+ }
+ public function wait(bool $unwrap = \true)
+ {
+ if ($unwrap) {
+ throw Create::exceptionFor($this->reason);
+ }
+ return null;
+ }
+ public function getState() : string
+ {
+ return self::REJECTED;
+ }
+ public function resolve($value) : void
+ {
+ throw new \LogicException('Cannot resolve a rejected promise');
+ }
+ public function reject($reason) : void
+ {
+ if ($reason !== $this->reason) {
+ throw new \LogicException('Cannot reject a rejected promise');
+ }
+ }
+ public function cancel() : void
+ {
+ // pass
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/promises/src/RejectionException.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/promises/src/RejectionException.php
new file mode 100755
index 00000000..41cb9a77
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/promises/src/RejectionException.php
@@ -0,0 +1,41 @@
+reason = $reason;
+ $message = 'The promise was rejected';
+ if ($description) {
+ $message .= ' with reason: ' . $description;
+ } elseif (\is_string($reason) || \is_object($reason) && \method_exists($reason, '__toString')) {
+ $message .= ' with reason: ' . $this->reason;
+ } elseif ($reason instanceof \JsonSerializable) {
+ $message .= ' with reason: ' . \json_encode($this->reason, \JSON_PRETTY_PRINT);
+ }
+ parent::__construct($message);
+ }
+ /**
+ * Returns the rejection reason.
+ *
+ * @return mixed
+ */
+ public function getReason()
+ {
+ return $this->reason;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/promises/src/TaskQueue.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/promises/src/TaskQueue.php
new file mode 100755
index 00000000..197e8b13
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/promises/src/TaskQueue.php
@@ -0,0 +1,65 @@
+run();
+ *
+ * @final
+ */
+class TaskQueue implements TaskQueueInterface
+{
+ private $enableShutdown = \true;
+ private $queue = [];
+ public function __construct(bool $withShutdown = \true)
+ {
+ if ($withShutdown) {
+ \register_shutdown_function(function () : void {
+ if ($this->enableShutdown) {
+ // Only run the tasks if an E_ERROR didn't occur.
+ $err = \error_get_last();
+ if (!$err || $err['type'] ^ \E_ERROR) {
+ $this->run();
+ }
+ }
+ });
+ }
+ }
+ public function isEmpty() : bool
+ {
+ return !$this->queue;
+ }
+ public function add(callable $task) : void
+ {
+ $this->queue[] = $task;
+ }
+ public function run() : void
+ {
+ while ($task = \array_shift($this->queue)) {
+ /** @var callable $task */
+ $task();
+ }
+ }
+ /**
+ * The task queue will be run and exhausted by default when the process
+ * exits IFF the exit is not the result of a PHP E_ERROR error.
+ *
+ * You can disable running the automatic shutdown of the queue by calling
+ * this function. If you disable the task queue shutdown process, then you
+ * MUST either run the task queue (as a result of running your event loop
+ * or manually using the run() method) or wait on each outstanding promise.
+ *
+ * Note: This shutdown will occur before any destructors are triggered.
+ */
+ public function disableShutdown() : void
+ {
+ $this->enableShutdown = \false;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/promises/src/TaskQueueInterface.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/promises/src/TaskQueueInterface.php
new file mode 100755
index 00000000..1861713f
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/promises/src/TaskQueueInterface.php
@@ -0,0 +1,21 @@
+
+ * while ($eventLoop->isRunning()) {
+ * GuzzleHttp\Promise\Utils::queue()->run();
+ * }
+ *
+ *
+ * @param TaskQueueInterface|null $assign Optionally specify a new queue instance.
+ */
+ public static function queue(?TaskQueueInterface $assign = null) : TaskQueueInterface
+ {
+ static $queue;
+ if ($assign) {
+ $queue = $assign;
+ } elseif (!$queue) {
+ $queue = new TaskQueue();
+ }
+ return $queue;
+ }
+ /**
+ * Adds a function to run in the task queue when it is next `run()` and
+ * returns a promise that is fulfilled or rejected with the result.
+ *
+ * @param callable $task Task function to run.
+ */
+ public static function task(callable $task) : PromiseInterface
+ {
+ $queue = self::queue();
+ $promise = new Promise([$queue, 'run']);
+ $queue->add(function () use($task, $promise) : void {
+ try {
+ if (Is::pending($promise)) {
+ $promise->resolve($task());
+ }
+ } catch (\Throwable $e) {
+ $promise->reject($e);
+ }
+ });
+ return $promise;
+ }
+ /**
+ * Synchronously waits on a promise to resolve and returns an inspection
+ * state array.
+ *
+ * Returns a state associative array containing a "state" key mapping to a
+ * valid promise state. If the state of the promise is "fulfilled", the
+ * array will contain a "value" key mapping to the fulfilled value of the
+ * promise. If the promise is rejected, the array will contain a "reason"
+ * key mapping to the rejection reason of the promise.
+ *
+ * @param PromiseInterface $promise Promise or value.
+ */
+ public static function inspect(PromiseInterface $promise) : array
+ {
+ try {
+ return ['state' => PromiseInterface::FULFILLED, 'value' => $promise->wait()];
+ } catch (RejectionException $e) {
+ return ['state' => PromiseInterface::REJECTED, 'reason' => $e->getReason()];
+ } catch (\Throwable $e) {
+ return ['state' => PromiseInterface::REJECTED, 'reason' => $e];
+ }
+ }
+ /**
+ * Waits on all of the provided promises, but does not unwrap rejected
+ * promises as thrown exception.
+ *
+ * Returns an array of inspection state arrays.
+ *
+ * @see inspect for the inspection state array format.
+ *
+ * @param PromiseInterface[] $promises Traversable of promises to wait upon.
+ */
+ public static function inspectAll($promises) : array
+ {
+ $results = [];
+ foreach ($promises as $key => $promise) {
+ $results[$key] = self::inspect($promise);
+ }
+ return $results;
+ }
+ /**
+ * Waits on all of the provided promises and returns the fulfilled values.
+ *
+ * Returns an array that contains the value of each promise (in the same
+ * order the promises were provided). An exception is thrown if any of the
+ * promises are rejected.
+ *
+ * @param iterable $promises Iterable of PromiseInterface objects to wait on.
+ *
+ * @throws \Throwable on error
+ */
+ public static function unwrap($promises) : array
+ {
+ $results = [];
+ foreach ($promises as $key => $promise) {
+ $results[$key] = $promise->wait();
+ }
+ return $results;
+ }
+ /**
+ * Given an array of promises, return a promise that is fulfilled when all
+ * the items in the array are fulfilled.
+ *
+ * The promise's fulfillment value is an array with fulfillment values at
+ * respective positions to the original array. If any promise in the array
+ * rejects, the returned promise is rejected with the rejection reason.
+ *
+ * @param mixed $promises Promises or values.
+ * @param bool $recursive If true, resolves new promises that might have been added to the stack during its own resolution.
+ */
+ public static function all($promises, bool $recursive = \false) : PromiseInterface
+ {
+ $results = [];
+ $promise = Each::of($promises, function ($value, $idx) use(&$results) : void {
+ $results[$idx] = $value;
+ }, function ($reason, $idx, Promise $aggregate) : void {
+ if (Is::pending($aggregate)) {
+ $aggregate->reject($reason);
+ }
+ })->then(function () use(&$results) {
+ \ksort($results);
+ return $results;
+ });
+ if (\true === $recursive) {
+ $promise = $promise->then(function ($results) use($recursive, &$promises) {
+ foreach ($promises as $promise) {
+ if (Is::pending($promise)) {
+ return self::all($promises, $recursive);
+ }
+ }
+ return $results;
+ });
+ }
+ return $promise;
+ }
+ /**
+ * Initiate a competitive race between multiple promises or values (values
+ * will become immediately fulfilled promises).
+ *
+ * When count amount of promises have been fulfilled, the returned promise
+ * is fulfilled with an array that contains the fulfillment values of the
+ * winners in order of resolution.
+ *
+ * This promise is rejected with a {@see AggregateException} if the number
+ * of fulfilled promises is less than the desired $count.
+ *
+ * @param int $count Total number of promises.
+ * @param mixed $promises Promises or values.
+ */
+ public static function some(int $count, $promises) : PromiseInterface
+ {
+ $results = [];
+ $rejections = [];
+ return Each::of($promises, function ($value, $idx, PromiseInterface $p) use(&$results, $count) : void {
+ if (Is::settled($p)) {
+ return;
+ }
+ $results[$idx] = $value;
+ if (\count($results) >= $count) {
+ $p->resolve(null);
+ }
+ }, function ($reason) use(&$rejections) : void {
+ $rejections[] = $reason;
+ })->then(function () use(&$results, &$rejections, $count) {
+ if (\count($results) !== $count) {
+ throw new AggregateException('Not enough promises to fulfill count', $rejections);
+ }
+ \ksort($results);
+ return \array_values($results);
+ });
+ }
+ /**
+ * Like some(), with 1 as count. However, if the promise fulfills, the
+ * fulfillment value is not an array of 1 but the value directly.
+ *
+ * @param mixed $promises Promises or values.
+ */
+ public static function any($promises) : PromiseInterface
+ {
+ return self::some(1, $promises)->then(function ($values) {
+ return $values[0];
+ });
+ }
+ /**
+ * Returns a promise that is fulfilled when all of the provided promises have
+ * been fulfilled or rejected.
+ *
+ * The returned promise is fulfilled with an array of inspection state arrays.
+ *
+ * @see inspect for the inspection state array format.
+ *
+ * @param mixed $promises Promises or values.
+ */
+ public static function settle($promises) : PromiseInterface
+ {
+ $results = [];
+ return Each::of($promises, function ($value, $idx) use(&$results) : void {
+ $results[$idx] = ['state' => PromiseInterface::FULFILLED, 'value' => $value];
+ }, function ($reason, $idx) use(&$results) : void {
+ $results[$idx] = ['state' => PromiseInterface::REJECTED, 'reason' => $reason];
+ })->then(function () use(&$results) {
+ \ksort($results);
+ return $results;
+ });
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/LICENSE b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/LICENSE
new file mode 100755
index 00000000..51c7ec81
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/LICENSE
@@ -0,0 +1,26 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 Michael Dowling
+Copyright (c) 2015 MƔrk SƔgi-KazƔr
+Copyright (c) 2015 Graham Campbell
+Copyright (c) 2016 Tobias Schultze
+Copyright (c) 2016 George Mponos
+Copyright (c) 2018 Tobias Nyholm
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/AppendStream.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/AppendStream.php
new file mode 100755
index 00000000..5e650c98
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/AppendStream.php
@@ -0,0 +1,203 @@
+addStream($stream);
+ }
+ }
+ public function __toString() : string
+ {
+ try {
+ $this->rewind();
+ return $this->getContents();
+ } catch (\Throwable $e) {
+ if (\PHP_VERSION_ID >= 70400) {
+ throw $e;
+ }
+ \trigger_error(\sprintf('%s::__toString exception: %s', self::class, (string) $e), \E_USER_ERROR);
+ return '';
+ }
+ }
+ /**
+ * Add a stream to the AppendStream
+ *
+ * @param StreamInterface $stream Stream to append. Must be readable.
+ *
+ * @throws \InvalidArgumentException if the stream is not readable
+ */
+ public function addStream(StreamInterface $stream) : void
+ {
+ if (!$stream->isReadable()) {
+ throw new \InvalidArgumentException('Each stream must be readable');
+ }
+ // The stream is only seekable if all streams are seekable
+ if (!$stream->isSeekable()) {
+ $this->seekable = \false;
+ }
+ $this->streams[] = $stream;
+ }
+ public function getContents() : string
+ {
+ return Utils::copyToString($this);
+ }
+ /**
+ * Closes each attached stream.
+ */
+ public function close() : void
+ {
+ $this->pos = $this->current = 0;
+ $this->seekable = \true;
+ foreach ($this->streams as $stream) {
+ $stream->close();
+ }
+ $this->streams = [];
+ }
+ /**
+ * Detaches each attached stream.
+ *
+ * Returns null as it's not clear which underlying stream resource to return.
+ */
+ public function detach()
+ {
+ $this->pos = $this->current = 0;
+ $this->seekable = \true;
+ foreach ($this->streams as $stream) {
+ $stream->detach();
+ }
+ $this->streams = [];
+ return null;
+ }
+ public function tell() : int
+ {
+ return $this->pos;
+ }
+ /**
+ * Tries to calculate the size by adding the size of each stream.
+ *
+ * If any of the streams do not return a valid number, then the size of the
+ * append stream cannot be determined and null is returned.
+ */
+ public function getSize() : ?int
+ {
+ $size = 0;
+ foreach ($this->streams as $stream) {
+ $s = $stream->getSize();
+ if ($s === null) {
+ return null;
+ }
+ $size += $s;
+ }
+ return $size;
+ }
+ public function eof() : bool
+ {
+ return !$this->streams || $this->current >= \count($this->streams) - 1 && $this->streams[$this->current]->eof();
+ }
+ public function rewind() : void
+ {
+ $this->seek(0);
+ }
+ /**
+ * Attempts to seek to the given position. Only supports SEEK_SET.
+ */
+ public function seek($offset, $whence = \SEEK_SET) : void
+ {
+ if (!$this->seekable) {
+ throw new \RuntimeException('This AppendStream is not seekable');
+ } elseif ($whence !== \SEEK_SET) {
+ throw new \RuntimeException('The AppendStream can only seek with SEEK_SET');
+ }
+ $this->pos = $this->current = 0;
+ // Rewind each stream
+ foreach ($this->streams as $i => $stream) {
+ try {
+ $stream->rewind();
+ } catch (\Exception $e) {
+ throw new \RuntimeException('Unable to seek stream ' . $i . ' of the AppendStream', 0, $e);
+ }
+ }
+ // Seek to the actual position by reading from each stream
+ while ($this->pos < $offset && !$this->eof()) {
+ $result = $this->read(\min(8096, $offset - $this->pos));
+ if ($result === '') {
+ break;
+ }
+ }
+ }
+ /**
+ * Reads from all of the appended streams until the length is met or EOF.
+ */
+ public function read($length) : string
+ {
+ $buffer = '';
+ $total = \count($this->streams) - 1;
+ $remaining = $length;
+ $progressToNext = \false;
+ while ($remaining > 0) {
+ // Progress to the next stream if needed.
+ if ($progressToNext || $this->streams[$this->current]->eof()) {
+ $progressToNext = \false;
+ if ($this->current === $total) {
+ break;
+ }
+ ++$this->current;
+ }
+ $result = $this->streams[$this->current]->read($remaining);
+ if ($result === '') {
+ $progressToNext = \true;
+ continue;
+ }
+ $buffer .= $result;
+ $remaining = $length - \strlen($buffer);
+ }
+ $this->pos += \strlen($buffer);
+ return $buffer;
+ }
+ public function isReadable() : bool
+ {
+ return \true;
+ }
+ public function isWritable() : bool
+ {
+ return \false;
+ }
+ public function isSeekable() : bool
+ {
+ return $this->seekable;
+ }
+ public function write($string) : int
+ {
+ throw new \RuntimeException('Cannot write to an AppendStream');
+ }
+ /**
+ * @return mixed
+ */
+ public function getMetadata($key = null)
+ {
+ return $key ? null : [];
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/BufferStream.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/BufferStream.php
new file mode 100755
index 00000000..20b59536
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/BufferStream.php
@@ -0,0 +1,121 @@
+hwm = $hwm;
+ }
+ public function __toString() : string
+ {
+ return $this->getContents();
+ }
+ public function getContents() : string
+ {
+ $buffer = $this->buffer;
+ $this->buffer = '';
+ return $buffer;
+ }
+ public function close() : void
+ {
+ $this->buffer = '';
+ }
+ public function detach()
+ {
+ $this->close();
+ return null;
+ }
+ public function getSize() : ?int
+ {
+ return \strlen($this->buffer);
+ }
+ public function isReadable() : bool
+ {
+ return \true;
+ }
+ public function isWritable() : bool
+ {
+ return \true;
+ }
+ public function isSeekable() : bool
+ {
+ return \false;
+ }
+ public function rewind() : void
+ {
+ $this->seek(0);
+ }
+ public function seek($offset, $whence = \SEEK_SET) : void
+ {
+ throw new \RuntimeException('Cannot seek a BufferStream');
+ }
+ public function eof() : bool
+ {
+ return \strlen($this->buffer) === 0;
+ }
+ public function tell() : int
+ {
+ throw new \RuntimeException('Cannot determine the position of a BufferStream');
+ }
+ /**
+ * Reads data from the buffer.
+ */
+ public function read($length) : string
+ {
+ $currentLength = \strlen($this->buffer);
+ if ($length >= $currentLength) {
+ // No need to slice the buffer because we don't have enough data.
+ $result = $this->buffer;
+ $this->buffer = '';
+ } else {
+ // Slice up the result to provide a subset of the buffer.
+ $result = \substr($this->buffer, 0, $length);
+ $this->buffer = \substr($this->buffer, $length);
+ }
+ return $result;
+ }
+ /**
+ * Writes data to the buffer.
+ */
+ public function write($string) : int
+ {
+ $this->buffer .= $string;
+ if (\strlen($this->buffer) >= $this->hwm) {
+ return 0;
+ }
+ return \strlen($string);
+ }
+ /**
+ * @return mixed
+ */
+ public function getMetadata($key = null)
+ {
+ if ($key === 'hwm') {
+ return $this->hwm;
+ }
+ return $key ? null : [];
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/CachingStream.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/CachingStream.php
new file mode 100755
index 00000000..021e6a07
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/CachingStream.php
@@ -0,0 +1,125 @@
+remoteStream = $stream;
+ $this->stream = $target ?: new Stream(Utils::tryFopen('php://temp', 'r+'));
+ }
+ public function getSize() : ?int
+ {
+ $remoteSize = $this->remoteStream->getSize();
+ if (null === $remoteSize) {
+ return null;
+ }
+ return \max($this->stream->getSize(), $remoteSize);
+ }
+ public function rewind() : void
+ {
+ $this->seek(0);
+ }
+ public function seek($offset, $whence = \SEEK_SET) : void
+ {
+ if ($whence === \SEEK_SET) {
+ $byte = $offset;
+ } elseif ($whence === \SEEK_CUR) {
+ $byte = $offset + $this->tell();
+ } elseif ($whence === \SEEK_END) {
+ $size = $this->remoteStream->getSize();
+ if ($size === null) {
+ $size = $this->cacheEntireStream();
+ }
+ $byte = $size + $offset;
+ } else {
+ throw new \InvalidArgumentException('Invalid whence');
+ }
+ $diff = $byte - $this->stream->getSize();
+ if ($diff > 0) {
+ // Read the remoteStream until we have read in at least the amount
+ // of bytes requested, or we reach the end of the file.
+ while ($diff > 0 && !$this->remoteStream->eof()) {
+ $this->read($diff);
+ $diff = $byte - $this->stream->getSize();
+ }
+ } else {
+ // We can just do a normal seek since we've already seen this byte.
+ $this->stream->seek($byte);
+ }
+ }
+ public function read($length) : string
+ {
+ // Perform a regular read on any previously read data from the buffer
+ $data = $this->stream->read($length);
+ $remaining = $length - \strlen($data);
+ // More data was requested so read from the remote stream
+ if ($remaining) {
+ // If data was written to the buffer in a position that would have
+ // been filled from the remote stream, then we must skip bytes on
+ // the remote stream to emulate overwriting bytes from that
+ // position. This mimics the behavior of other PHP stream wrappers.
+ $remoteData = $this->remoteStream->read($remaining + $this->skipReadBytes);
+ if ($this->skipReadBytes) {
+ $len = \strlen($remoteData);
+ $remoteData = \substr($remoteData, $this->skipReadBytes);
+ $this->skipReadBytes = \max(0, $this->skipReadBytes - $len);
+ }
+ $data .= $remoteData;
+ $this->stream->write($remoteData);
+ }
+ return $data;
+ }
+ public function write($string) : int
+ {
+ // When appending to the end of the currently read stream, you'll want
+ // to skip bytes from being read from the remote stream to emulate
+ // other stream wrappers. Basically replacing bytes of data of a fixed
+ // length.
+ $overflow = \strlen($string) + $this->tell() - $this->remoteStream->tell();
+ if ($overflow > 0) {
+ $this->skipReadBytes += $overflow;
+ }
+ return $this->stream->write($string);
+ }
+ public function eof() : bool
+ {
+ return $this->stream->eof() && $this->remoteStream->eof();
+ }
+ /**
+ * Close both the remote stream and buffer stream
+ */
+ public function close() : void
+ {
+ $this->remoteStream->close();
+ $this->stream->close();
+ }
+ private function cacheEntireStream() : int
+ {
+ $target = new FnStream(['write' => 'strlen']);
+ Utils::copyToStream($this, $target);
+ return $this->tell();
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/DroppingStream.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/DroppingStream.php
new file mode 100755
index 00000000..1fa849f0
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/DroppingStream.php
@@ -0,0 +1,40 @@
+stream = $stream;
+ $this->maxLength = $maxLength;
+ }
+ public function write($string) : int
+ {
+ $diff = $this->maxLength - $this->stream->getSize();
+ // Begin returning 0 when the underlying stream is too large.
+ if ($diff <= 0) {
+ return 0;
+ }
+ // Write the stream or a subset of the stream if needed.
+ if (\strlen($string) < $diff) {
+ return $this->stream->write($string);
+ }
+ return $this->stream->write(\substr($string, 0, $diff));
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/Exception/MalformedUriException.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/Exception/MalformedUriException.php
new file mode 100755
index 00000000..e0131d35
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/Exception/MalformedUriException.php
@@ -0,0 +1,12 @@
+ */
+ private $methods;
+ /**
+ * @param array $methods Hash of method name to a callable.
+ */
+ public function __construct(array $methods)
+ {
+ $this->methods = $methods;
+ // Create the functions on the class
+ foreach ($methods as $name => $fn) {
+ $this->{'_fn_' . $name} = $fn;
+ }
+ }
+ /**
+ * Lazily determine which methods are not implemented.
+ *
+ * @throws \BadMethodCallException
+ */
+ public function __get(string $name) : void
+ {
+ throw new \BadMethodCallException(\str_replace('_fn_', '', $name) . '() is not implemented in the FnStream');
+ }
+ /**
+ * The close method is called on the underlying stream only if possible.
+ */
+ public function __destruct()
+ {
+ if (isset($this->_fn_close)) {
+ ($this->_fn_close)();
+ }
+ }
+ /**
+ * An unserialize would allow the __destruct to run when the unserialized value goes out of scope.
+ *
+ * @throws \LogicException
+ */
+ public function __wakeup() : void
+ {
+ throw new \LogicException('FnStream should never be unserialized');
+ }
+ /**
+ * Adds custom functionality to an underlying stream by intercepting
+ * specific method calls.
+ *
+ * @param StreamInterface $stream Stream to decorate
+ * @param array $methods Hash of method name to a closure
+ *
+ * @return FnStream
+ */
+ public static function decorate(StreamInterface $stream, array $methods)
+ {
+ // If any of the required methods were not provided, then simply
+ // proxy to the decorated stream.
+ foreach (\array_diff(self::SLOTS, \array_keys($methods)) as $diff) {
+ /** @var callable $callable */
+ $callable = [$stream, $diff];
+ $methods[$diff] = $callable;
+ }
+ return new self($methods);
+ }
+ public function __toString() : string
+ {
+ try {
+ /** @var string */
+ return ($this->_fn___toString)();
+ } catch (\Throwable $e) {
+ if (\PHP_VERSION_ID >= 70400) {
+ throw $e;
+ }
+ \trigger_error(\sprintf('%s::__toString exception: %s', self::class, (string) $e), \E_USER_ERROR);
+ return '';
+ }
+ }
+ public function close() : void
+ {
+ ($this->_fn_close)();
+ }
+ public function detach()
+ {
+ return ($this->_fn_detach)();
+ }
+ public function getSize() : ?int
+ {
+ return ($this->_fn_getSize)();
+ }
+ public function tell() : int
+ {
+ return ($this->_fn_tell)();
+ }
+ public function eof() : bool
+ {
+ return ($this->_fn_eof)();
+ }
+ public function isSeekable() : bool
+ {
+ return ($this->_fn_isSeekable)();
+ }
+ public function rewind() : void
+ {
+ ($this->_fn_rewind)();
+ }
+ public function seek($offset, $whence = \SEEK_SET) : void
+ {
+ ($this->_fn_seek)($offset, $whence);
+ }
+ public function isWritable() : bool
+ {
+ return ($this->_fn_isWritable)();
+ }
+ public function write($string) : int
+ {
+ return ($this->_fn_write)($string);
+ }
+ public function isReadable() : bool
+ {
+ return ($this->_fn_isReadable)();
+ }
+ public function read($length) : string
+ {
+ return ($this->_fn_read)($length);
+ }
+ public function getContents() : string
+ {
+ return ($this->_fn_getContents)();
+ }
+ /**
+ * @return mixed
+ */
+ public function getMetadata($key = null)
+ {
+ return ($this->_fn_getMetadata)($key);
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/Header.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/Header.php
new file mode 100755
index 00000000..a00f3fb7
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/Header.php
@@ -0,0 +1,117 @@
+]+>|[^=]+/', $kvp, $matches)) {
+ $m = $matches[0];
+ if (isset($m[1])) {
+ $part[\trim($m[0], $trimmed)] = \trim($m[1], $trimmed);
+ } else {
+ $part[] = \trim($m[0], $trimmed);
+ }
+ }
+ }
+ if ($part) {
+ $params[] = $part;
+ }
+ }
+ }
+ return $params;
+ }
+ /**
+ * Converts an array of header values that may contain comma separated
+ * headers into an array of headers with no comma separated values.
+ *
+ * @param string|array $header Header to normalize.
+ *
+ * @deprecated Use self::splitList() instead.
+ */
+ public static function normalize($header) : array
+ {
+ $result = [];
+ foreach ((array) $header as $value) {
+ foreach (self::splitList($value) as $parsed) {
+ $result[] = $parsed;
+ }
+ }
+ return $result;
+ }
+ /**
+ * Splits a HTTP header defined to contain a comma-separated list into
+ * each individual value. Empty values will be removed.
+ *
+ * Example headers include 'accept', 'cache-control' and 'if-none-match'.
+ *
+ * This method must not be used to parse headers that are not defined as
+ * a list, such as 'user-agent' or 'set-cookie'.
+ *
+ * @param string|string[] $values Header value as returned by MessageInterface::getHeader()
+ *
+ * @return string[]
+ */
+ public static function splitList($values) : array
+ {
+ if (!\is_array($values)) {
+ $values = [$values];
+ }
+ $result = [];
+ foreach ($values as $value) {
+ if (!\is_string($value)) {
+ throw new \TypeError('$header must either be a string or an array containing strings.');
+ }
+ $v = '';
+ $isQuoted = \false;
+ $isEscaped = \false;
+ for ($i = 0, $max = \strlen($value); $i < $max; ++$i) {
+ if ($isEscaped) {
+ $v .= $value[$i];
+ $isEscaped = \false;
+ continue;
+ }
+ if (!$isQuoted && $value[$i] === ',') {
+ $v = \trim($v);
+ if ($v !== '') {
+ $result[] = $v;
+ }
+ $v = '';
+ continue;
+ }
+ if ($isQuoted && $value[$i] === '\\') {
+ $isEscaped = \true;
+ $v .= $value[$i];
+ continue;
+ }
+ if ($value[$i] === '"') {
+ $isQuoted = !$isQuoted;
+ $v .= $value[$i];
+ continue;
+ }
+ $v .= $value[$i];
+ }
+ $v = \trim($v);
+ if ($v !== '') {
+ $result[] = $v;
+ }
+ }
+ return $result;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/HttpFactory.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/HttpFactory.php
new file mode 100755
index 00000000..8f552bbf
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/HttpFactory.php
@@ -0,0 +1,76 @@
+getSize();
+ }
+ return new UploadedFile($stream, $size, $error, $clientFilename, $clientMediaType);
+ }
+ public function createStream(string $content = '') : StreamInterface
+ {
+ return Utils::streamFor($content);
+ }
+ public function createStreamFromFile(string $file, string $mode = 'r') : StreamInterface
+ {
+ try {
+ $resource = Utils::tryFopen($file, $mode);
+ } catch (\RuntimeException $e) {
+ if ('' === $mode || \false === \in_array($mode[0], ['r', 'w', 'a', 'x', 'c'], \true)) {
+ throw new \InvalidArgumentException(\sprintf('Invalid file opening mode "%s"', $mode), 0, $e);
+ }
+ throw $e;
+ }
+ return Utils::streamFor($resource);
+ }
+ public function createStreamFromResource($resource) : StreamInterface
+ {
+ return Utils::streamFor($resource);
+ }
+ public function createServerRequest(string $method, $uri, array $serverParams = []) : ServerRequestInterface
+ {
+ if (empty($method)) {
+ if (!empty($serverParams['REQUEST_METHOD'])) {
+ $method = $serverParams['REQUEST_METHOD'];
+ } else {
+ throw new \InvalidArgumentException('Cannot determine HTTP method');
+ }
+ }
+ return new ServerRequest($method, $uri, [], null, '1.1', $serverParams);
+ }
+ public function createResponse(int $code = 200, string $reasonPhrase = '') : ResponseInterface
+ {
+ return new Response($code, [], null, '1.1', $reasonPhrase);
+ }
+ public function createRequest(string $method, $uri) : RequestInterface
+ {
+ return new Request($method, $uri);
+ }
+ public function createUri(string $uri = '') : UriInterface
+ {
+ return new Uri($uri);
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/InflateStream.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/InflateStream.php
new file mode 100755
index 00000000..ee972434
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/InflateStream.php
@@ -0,0 +1,33 @@
+ 15 + 32]);
+ $this->stream = $stream->isSeekable() ? new Stream($resource) : new NoSeekStream(new Stream($resource));
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/LazyOpenStream.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/LazyOpenStream.php
new file mode 100755
index 00000000..45579a05
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/LazyOpenStream.php
@@ -0,0 +1,41 @@
+filename = $filename;
+ $this->mode = $mode;
+ // unsetting the property forces the first access to go through
+ // __get().
+ unset($this->stream);
+ }
+ /**
+ * Creates the underlying stream lazily when required.
+ */
+ protected function createStream() : StreamInterface
+ {
+ return Utils::streamFor(Utils::tryFopen($this->filename, $this->mode));
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/LimitStream.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/LimitStream.php
new file mode 100755
index 00000000..7b83dfb9
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/LimitStream.php
@@ -0,0 +1,128 @@
+stream = $stream;
+ $this->setLimit($limit);
+ $this->setOffset($offset);
+ }
+ public function eof() : bool
+ {
+ // Always return true if the underlying stream is EOF
+ if ($this->stream->eof()) {
+ return \true;
+ }
+ // No limit and the underlying stream is not at EOF
+ if ($this->limit === -1) {
+ return \false;
+ }
+ return $this->stream->tell() >= $this->offset + $this->limit;
+ }
+ /**
+ * Returns the size of the limited subset of data
+ */
+ public function getSize() : ?int
+ {
+ if (null === ($length = $this->stream->getSize())) {
+ return null;
+ } elseif ($this->limit === -1) {
+ return $length - $this->offset;
+ } else {
+ return \min($this->limit, $length - $this->offset);
+ }
+ }
+ /**
+ * Allow for a bounded seek on the read limited stream
+ */
+ public function seek($offset, $whence = \SEEK_SET) : void
+ {
+ if ($whence !== \SEEK_SET || $offset < 0) {
+ throw new \RuntimeException(\sprintf('Cannot seek to offset %s with whence %s', $offset, $whence));
+ }
+ $offset += $this->offset;
+ if ($this->limit !== -1) {
+ if ($offset > $this->offset + $this->limit) {
+ $offset = $this->offset + $this->limit;
+ }
+ }
+ $this->stream->seek($offset);
+ }
+ /**
+ * Give a relative tell()
+ */
+ public function tell() : int
+ {
+ return $this->stream->tell() - $this->offset;
+ }
+ /**
+ * Set the offset to start limiting from
+ *
+ * @param int $offset Offset to seek to and begin byte limiting from
+ *
+ * @throws \RuntimeException if the stream cannot be seeked.
+ */
+ public function setOffset(int $offset) : void
+ {
+ $current = $this->stream->tell();
+ if ($current !== $offset) {
+ // If the stream cannot seek to the offset position, then read to it
+ if ($this->stream->isSeekable()) {
+ $this->stream->seek($offset);
+ } elseif ($current > $offset) {
+ throw new \RuntimeException("Could not seek to stream offset {$offset}");
+ } else {
+ $this->stream->read($offset - $current);
+ }
+ }
+ $this->offset = $offset;
+ }
+ /**
+ * Set the limit of bytes that the decorator allows to be read from the
+ * stream.
+ *
+ * @param int $limit Number of bytes to allow to be read from the stream.
+ * Use -1 for no limit.
+ */
+ public function setLimit(int $limit) : void
+ {
+ $this->limit = $limit;
+ }
+ public function read($length) : string
+ {
+ if ($this->limit === -1) {
+ return $this->stream->read($length);
+ }
+ // Check if the current position is less than the total allowed
+ // bytes + original offset
+ $remaining = $this->offset + $this->limit - $this->stream->tell();
+ if ($remaining > 0) {
+ // Only return the amount of requested data, ensuring that the byte
+ // limit is not exceeded
+ return $this->stream->read(\min($remaining, $length));
+ }
+ return '';
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/Message.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/Message.php
new file mode 100755
index 00000000..6063214a
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/Message.php
@@ -0,0 +1,189 @@
+getMethod() . ' ' . $message->getRequestTarget()) . ' HTTP/' . $message->getProtocolVersion();
+ if (!$message->hasHeader('host')) {
+ $msg .= "\r\nHost: " . $message->getUri()->getHost();
+ }
+ } elseif ($message instanceof ResponseInterface) {
+ $msg = 'HTTP/' . $message->getProtocolVersion() . ' ' . $message->getStatusCode() . ' ' . $message->getReasonPhrase();
+ } else {
+ throw new \InvalidArgumentException('Unknown message type');
+ }
+ foreach ($message->getHeaders() as $name => $values) {
+ if (\is_string($name) && \strtolower($name) === 'set-cookie') {
+ foreach ($values as $value) {
+ $msg .= "\r\n{$name}: " . $value;
+ }
+ } else {
+ $msg .= "\r\n{$name}: " . \implode(', ', $values);
+ }
+ }
+ return "{$msg}\r\n\r\n" . $message->getBody();
+ }
+ /**
+ * Get a short summary of the message body.
+ *
+ * Will return `null` if the response is not printable.
+ *
+ * @param MessageInterface $message The message to get the body summary
+ * @param int $truncateAt The maximum allowed size of the summary
+ */
+ public static function bodySummary(MessageInterface $message, int $truncateAt = 120) : ?string
+ {
+ $body = $message->getBody();
+ if (!$body->isSeekable() || !$body->isReadable()) {
+ return null;
+ }
+ $size = $body->getSize();
+ if ($size === 0) {
+ return null;
+ }
+ $body->rewind();
+ $summary = $body->read($truncateAt);
+ $body->rewind();
+ if ($size > $truncateAt) {
+ $summary .= ' (truncated...)';
+ }
+ // Matches any printable character, including unicode characters:
+ // letters, marks, numbers, punctuation, spacing, and separators.
+ if (\preg_match('/[^\\pL\\pM\\pN\\pP\\pS\\pZ\\n\\r\\t]/u', $summary) !== 0) {
+ return null;
+ }
+ return $summary;
+ }
+ /**
+ * Attempts to rewind a message body and throws an exception on failure.
+ *
+ * The body of the message will only be rewound if a call to `tell()`
+ * returns a value other than `0`.
+ *
+ * @param MessageInterface $message Message to rewind
+ *
+ * @throws \RuntimeException
+ */
+ public static function rewindBody(MessageInterface $message) : void
+ {
+ $body = $message->getBody();
+ if ($body->tell()) {
+ $body->rewind();
+ }
+ }
+ /**
+ * Parses an HTTP message into an associative array.
+ *
+ * The array contains the "start-line" key containing the start line of
+ * the message, "headers" key containing an associative array of header
+ * array values, and a "body" key containing the body of the message.
+ *
+ * @param string $message HTTP request or response to parse.
+ */
+ public static function parseMessage(string $message) : array
+ {
+ if (!$message) {
+ throw new \InvalidArgumentException('Invalid message');
+ }
+ $message = \ltrim($message, "\r\n");
+ $messageParts = \preg_split("/\r?\n\r?\n/", $message, 2);
+ if ($messageParts === \false || \count($messageParts) !== 2) {
+ throw new \InvalidArgumentException('Invalid message: Missing header delimiter');
+ }
+ [$rawHeaders, $body] = $messageParts;
+ $rawHeaders .= "\r\n";
+ // Put back the delimiter we split previously
+ $headerParts = \preg_split("/\r?\n/", $rawHeaders, 2);
+ if ($headerParts === \false || \count($headerParts) !== 2) {
+ throw new \InvalidArgumentException('Invalid message: Missing status line');
+ }
+ [$startLine, $rawHeaders] = $headerParts;
+ if (\preg_match("/(?:^HTTP\\/|^[A-Z]+ \\S+ HTTP\\/)(\\d+(?:\\.\\d+)?)/i", $startLine, $matches) && $matches[1] === '1.0') {
+ // Header folding is deprecated for HTTP/1.1, but allowed in HTTP/1.0
+ $rawHeaders = \preg_replace(Rfc7230::HEADER_FOLD_REGEX, ' ', $rawHeaders);
+ }
+ /** @var array[] $headerLines */
+ $count = \preg_match_all(Rfc7230::HEADER_REGEX, $rawHeaders, $headerLines, \PREG_SET_ORDER);
+ // If these aren't the same, then one line didn't match and there's an invalid header.
+ if ($count !== \substr_count($rawHeaders, "\n")) {
+ // Folding is deprecated, see https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.4
+ if (\preg_match(Rfc7230::HEADER_FOLD_REGEX, $rawHeaders)) {
+ throw new \InvalidArgumentException('Invalid header syntax: Obsolete line folding');
+ }
+ throw new \InvalidArgumentException('Invalid header syntax');
+ }
+ $headers = [];
+ foreach ($headerLines as $headerLine) {
+ $headers[$headerLine[1]][] = $headerLine[2];
+ }
+ return ['start-line' => $startLine, 'headers' => $headers, 'body' => $body];
+ }
+ /**
+ * Constructs a URI for an HTTP request message.
+ *
+ * @param string $path Path from the start-line
+ * @param array $headers Array of headers (each value an array).
+ */
+ public static function parseRequestUri(string $path, array $headers) : string
+ {
+ $hostKey = \array_filter(\array_keys($headers), function ($k) {
+ // Numeric array keys are converted to int by PHP.
+ $k = (string) $k;
+ return \strtolower($k) === 'host';
+ });
+ // If no host is found, then a full URI cannot be constructed.
+ if (!$hostKey) {
+ return $path;
+ }
+ $host = $headers[\reset($hostKey)][0];
+ $scheme = \substr($host, -4) === ':443' ? 'https' : 'http';
+ return $scheme . '://' . $host . '/' . \ltrim($path, '/');
+ }
+ /**
+ * Parses a request message string into a request object.
+ *
+ * @param string $message Request message string.
+ */
+ public static function parseRequest(string $message) : RequestInterface
+ {
+ $data = self::parseMessage($message);
+ $matches = [];
+ if (!\preg_match('/^[\\S]+\\s+([a-zA-Z]+:\\/\\/|\\/).*/', $data['start-line'], $matches)) {
+ throw new \InvalidArgumentException('Invalid request string');
+ }
+ $parts = \explode(' ', $data['start-line'], 3);
+ $version = isset($parts[2]) ? \explode('/', $parts[2])[1] : '1.1';
+ $request = new Request($parts[0], $matches[1] === '/' ? self::parseRequestUri($parts[1], $data['headers']) : $parts[1], $data['headers'], $data['body'], $version);
+ return $matches[1] === '/' ? $request : $request->withRequestTarget($parts[1]);
+ }
+ /**
+ * Parses a response message string into a response object.
+ *
+ * @param string $message Response message string.
+ */
+ public static function parseResponse(string $message) : ResponseInterface
+ {
+ $data = self::parseMessage($message);
+ // According to https://datatracker.ietf.org/doc/html/rfc7230#section-3.1.2
+ // the space between status-code and reason-phrase is required. But
+ // browsers accept responses without space and reason as well.
+ if (!\preg_match('/^HTTP\\/.* [0-9]{3}( .*|$)/', $data['start-line'])) {
+ throw new \InvalidArgumentException('Invalid response string: ' . $data['start-line']);
+ }
+ $parts = \explode(' ', $data['start-line'], 3);
+ return new Response((int) $parts[1], $data['headers'], $data['body'], \explode('/', $parts[0])[1], $parts[2] ?? null);
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/MessageTrait.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/MessageTrait.php
new file mode 100755
index 00000000..fb1871bb
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/MessageTrait.php
@@ -0,0 +1,209 @@
+ array of values */
+ private $headers = [];
+ /** @var string[] Map of lowercase header name => original name at registration */
+ private $headerNames = [];
+ /** @var string */
+ private $protocol = '1.1';
+ /** @var StreamInterface|null */
+ private $stream;
+ public function getProtocolVersion() : string
+ {
+ return $this->protocol;
+ }
+ public function withProtocolVersion($version) : MessageInterface
+ {
+ if ($this->protocol === $version) {
+ return $this;
+ }
+ $new = clone $this;
+ $new->protocol = $version;
+ return $new;
+ }
+ public function getHeaders() : array
+ {
+ return $this->headers;
+ }
+ public function hasHeader($header) : bool
+ {
+ return isset($this->headerNames[\strtolower($header)]);
+ }
+ public function getHeader($header) : array
+ {
+ $header = \strtolower($header);
+ if (!isset($this->headerNames[$header])) {
+ return [];
+ }
+ $header = $this->headerNames[$header];
+ return $this->headers[$header];
+ }
+ public function getHeaderLine($header) : string
+ {
+ return \implode(', ', $this->getHeader($header));
+ }
+ public function withHeader($header, $value) : MessageInterface
+ {
+ $this->assertHeader($header);
+ $value = $this->normalizeHeaderValue($value);
+ $normalized = \strtolower($header);
+ $new = clone $this;
+ if (isset($new->headerNames[$normalized])) {
+ unset($new->headers[$new->headerNames[$normalized]]);
+ }
+ $new->headerNames[$normalized] = $header;
+ $new->headers[$header] = $value;
+ return $new;
+ }
+ public function withAddedHeader($header, $value) : MessageInterface
+ {
+ $this->assertHeader($header);
+ $value = $this->normalizeHeaderValue($value);
+ $normalized = \strtolower($header);
+ $new = clone $this;
+ if (isset($new->headerNames[$normalized])) {
+ $header = $this->headerNames[$normalized];
+ $new->headers[$header] = \array_merge($this->headers[$header], $value);
+ } else {
+ $new->headerNames[$normalized] = $header;
+ $new->headers[$header] = $value;
+ }
+ return $new;
+ }
+ public function withoutHeader($header) : MessageInterface
+ {
+ $normalized = \strtolower($header);
+ if (!isset($this->headerNames[$normalized])) {
+ return $this;
+ }
+ $header = $this->headerNames[$normalized];
+ $new = clone $this;
+ unset($new->headers[$header], $new->headerNames[$normalized]);
+ return $new;
+ }
+ public function getBody() : StreamInterface
+ {
+ if (!$this->stream) {
+ $this->stream = Utils::streamFor('');
+ }
+ return $this->stream;
+ }
+ public function withBody(StreamInterface $body) : MessageInterface
+ {
+ if ($body === $this->stream) {
+ return $this;
+ }
+ $new = clone $this;
+ $new->stream = $body;
+ return $new;
+ }
+ /**
+ * @param (string|string[])[] $headers
+ */
+ private function setHeaders(array $headers) : void
+ {
+ $this->headerNames = $this->headers = [];
+ foreach ($headers as $header => $value) {
+ // Numeric array keys are converted to int by PHP.
+ $header = (string) $header;
+ $this->assertHeader($header);
+ $value = $this->normalizeHeaderValue($value);
+ $normalized = \strtolower($header);
+ if (isset($this->headerNames[$normalized])) {
+ $header = $this->headerNames[$normalized];
+ $this->headers[$header] = \array_merge($this->headers[$header], $value);
+ } else {
+ $this->headerNames[$normalized] = $header;
+ $this->headers[$header] = $value;
+ }
+ }
+ }
+ /**
+ * @param mixed $value
+ *
+ * @return string[]
+ */
+ private function normalizeHeaderValue($value) : array
+ {
+ if (!\is_array($value)) {
+ return $this->trimAndValidateHeaderValues([$value]);
+ }
+ return $this->trimAndValidateHeaderValues($value);
+ }
+ /**
+ * Trims whitespace from the header values.
+ *
+ * Spaces and tabs ought to be excluded by parsers when extracting the field value from a header field.
+ *
+ * header-field = field-name ":" OWS field-value OWS
+ * OWS = *( SP / HTAB )
+ *
+ * @param mixed[] $values Header values
+ *
+ * @return string[] Trimmed header values
+ *
+ * @see https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.4
+ */
+ private function trimAndValidateHeaderValues(array $values) : array
+ {
+ return \array_map(function ($value) {
+ if (!\is_scalar($value) && null !== $value) {
+ throw new \InvalidArgumentException(\sprintf('Header value must be scalar or null but %s provided.', \is_object($value) ? \get_class($value) : \gettype($value)));
+ }
+ $trimmed = \trim((string) $value, " \t");
+ $this->assertValue($trimmed);
+ return $trimmed;
+ }, \array_values($values));
+ }
+ /**
+ * @see https://datatracker.ietf.org/doc/html/rfc7230#section-3.2
+ *
+ * @param mixed $header
+ */
+ private function assertHeader($header) : void
+ {
+ if (!\is_string($header)) {
+ throw new \InvalidArgumentException(\sprintf('Header name must be a string but %s provided.', \is_object($header) ? \get_class($header) : \gettype($header)));
+ }
+ if (!\preg_match('/^[a-zA-Z0-9\'`#$%&*+.^_|~!-]+$/D', $header)) {
+ throw new \InvalidArgumentException(\sprintf('"%s" is not valid header name.', $header));
+ }
+ }
+ /**
+ * @see https://datatracker.ietf.org/doc/html/rfc7230#section-3.2
+ *
+ * field-value = *( field-content / obs-fold )
+ * field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
+ * field-vchar = VCHAR / obs-text
+ * VCHAR = %x21-7E
+ * obs-text = %x80-FF
+ * obs-fold = CRLF 1*( SP / HTAB )
+ */
+ private function assertValue(string $value) : void
+ {
+ // The regular expression intentionally does not support the obs-fold production, because as
+ // per RFC 7230#3.2.4:
+ //
+ // A sender MUST NOT generate a message that includes
+ // line folding (i.e., that has any field-value that contains a match to
+ // the obs-fold rule) unless the message is intended for packaging
+ // within the message/http media type.
+ //
+ // Clients must not send a request with line folding and a server sending folded headers is
+ // likely very rare. Line folding is a fairly obscure feature of HTTP/1.1 and thus not accepting
+ // folding is not likely to break any legitimate use case.
+ if (!\preg_match('/^[\\x20\\x09\\x21-\\x7E\\x80-\\xFF]*$/D', $value)) {
+ throw new \InvalidArgumentException(\sprintf('"%s" is not valid header value.', $value));
+ }
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/MimeType.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/MimeType.php
new file mode 100755
index 00000000..ee215b86
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/MimeType.php
@@ -0,0 +1,27 @@
+ 'application/vnd.1000minds.decision-model+xml', '3dml' => 'text/vnd.in3d.3dml', '3ds' => 'image/x-3ds', '3g2' => 'video/3gpp2', '3gp' => 'video/3gp', '3gpp' => 'video/3gpp', '3mf' => 'model/3mf', '7z' => 'application/x-7z-compressed', '7zip' => 'application/x-7z-compressed', '123' => 'application/vnd.lotus-1-2-3', 'aab' => 'application/x-authorware-bin', 'aac' => 'audio/aac', 'aam' => 'application/x-authorware-map', 'aas' => 'application/x-authorware-seg', 'abw' => 'application/x-abiword', 'ac' => 'application/vnd.nokia.n-gage.ac+xml', 'ac3' => 'audio/ac3', 'acc' => 'application/vnd.americandynamics.acc', 'ace' => 'application/x-ace-compressed', 'acu' => 'application/vnd.acucobol', 'acutc' => 'application/vnd.acucorp', 'adp' => 'audio/adpcm', 'adts' => 'audio/aac', 'aep' => 'application/vnd.audiograph', 'afm' => 'application/x-font-type1', 'afp' => 'application/vnd.ibm.modcap', 'age' => 'application/vnd.age', 'ahead' => 'application/vnd.ahead.space', 'ai' => 'application/pdf', 'aif' => 'audio/x-aiff', 'aifc' => 'audio/x-aiff', 'aiff' => 'audio/x-aiff', 'air' => 'application/vnd.adobe.air-application-installer-package+zip', 'ait' => 'application/vnd.dvb.ait', 'ami' => 'application/vnd.amiga.ami', 'aml' => 'application/automationml-aml+xml', 'amlx' => 'application/automationml-amlx+zip', 'amr' => 'audio/amr', 'apk' => 'application/vnd.android.package-archive', 'apng' => 'image/apng', 'appcache' => 'text/cache-manifest', 'appinstaller' => 'application/appinstaller', 'application' => 'application/x-ms-application', 'appx' => 'application/appx', 'appxbundle' => 'application/appxbundle', 'apr' => 'application/vnd.lotus-approach', 'arc' => 'application/x-freearc', 'arj' => 'application/x-arj', 'asc' => 'application/pgp-signature', 'asf' => 'video/x-ms-asf', 'asm' => 'text/x-asm', 'aso' => 'application/vnd.accpac.simply.aso', 'asx' => 'video/x-ms-asf', 'atc' => 'application/vnd.acucorp', 'atom' => 'application/atom+xml', 'atomcat' => 'application/atomcat+xml', 'atomdeleted' => 'application/atomdeleted+xml', 'atomsvc' => 'application/atomsvc+xml', 'atx' => 'application/vnd.antix.game-component', 'au' => 'audio/x-au', 'avci' => 'image/avci', 'avcs' => 'image/avcs', 'avi' => 'video/x-msvideo', 'avif' => 'image/avif', 'aw' => 'application/applixware', 'azf' => 'application/vnd.airzip.filesecure.azf', 'azs' => 'application/vnd.airzip.filesecure.azs', 'azv' => 'image/vnd.airzip.accelerator.azv', 'azw' => 'application/vnd.amazon.ebook', 'b16' => 'image/vnd.pco.b16', 'bat' => 'application/x-msdownload', 'bcpio' => 'application/x-bcpio', 'bdf' => 'application/x-font-bdf', 'bdm' => 'application/vnd.syncml.dm+wbxml', 'bdoc' => 'application/x-bdoc', 'bed' => 'application/vnd.realvnc.bed', 'bh2' => 'application/vnd.fujitsu.oasysprs', 'bin' => 'application/octet-stream', 'blb' => 'application/x-blorb', 'blorb' => 'application/x-blorb', 'bmi' => 'application/vnd.bmi', 'bmml' => 'application/vnd.balsamiq.bmml+xml', 'bmp' => 'image/bmp', 'book' => 'application/vnd.framemaker', 'box' => 'application/vnd.previewsystems.box', 'boz' => 'application/x-bzip2', 'bpk' => 'application/octet-stream', 'bpmn' => 'application/octet-stream', 'bsp' => 'model/vnd.valve.source.compiled-map', 'btf' => 'image/prs.btif', 'btif' => 'image/prs.btif', 'buffer' => 'application/octet-stream', 'bz' => 'application/x-bzip', 'bz2' => 'application/x-bzip2', 'c' => 'text/x-c', 'c4d' => 'application/vnd.clonk.c4group', 'c4f' => 'application/vnd.clonk.c4group', 'c4g' => 'application/vnd.clonk.c4group', 'c4p' => 'application/vnd.clonk.c4group', 'c4u' => 'application/vnd.clonk.c4group', 'c11amc' => 'application/vnd.cluetrust.cartomobile-config', 'c11amz' => 'application/vnd.cluetrust.cartomobile-config-pkg', 'cab' => 'application/vnd.ms-cab-compressed', 'caf' => 'audio/x-caf', 'cap' => 'application/vnd.tcpdump.pcap', 'car' => 'application/vnd.curl.car', 'cat' => 'application/vnd.ms-pki.seccat', 'cb7' => 'application/x-cbr', 'cba' => 'application/x-cbr', 'cbr' => 'application/x-cbr', 'cbt' => 'application/x-cbr', 'cbz' => 'application/x-cbr', 'cc' => 'text/x-c', 'cco' => 'application/x-cocoa', 'cct' => 'application/x-director', 'ccxml' => 'application/ccxml+xml', 'cdbcmsg' => 'application/vnd.contact.cmsg', 'cdf' => 'application/x-netcdf', 'cdfx' => 'application/cdfx+xml', 'cdkey' => 'application/vnd.mediastation.cdkey', 'cdmia' => 'application/cdmi-capability', 'cdmic' => 'application/cdmi-container', 'cdmid' => 'application/cdmi-domain', 'cdmio' => 'application/cdmi-object', 'cdmiq' => 'application/cdmi-queue', 'cdr' => 'application/cdr', 'cdx' => 'chemical/x-cdx', 'cdxml' => 'application/vnd.chemdraw+xml', 'cdy' => 'application/vnd.cinderella', 'cer' => 'application/pkix-cert', 'cfs' => 'application/x-cfs-compressed', 'cgm' => 'image/cgm', 'chat' => 'application/x-chat', 'chm' => 'application/vnd.ms-htmlhelp', 'chrt' => 'application/vnd.kde.kchart', 'cif' => 'chemical/x-cif', 'cii' => 'application/vnd.anser-web-certificate-issue-initiation', 'cil' => 'application/vnd.ms-artgalry', 'cjs' => 'application/node', 'cla' => 'application/vnd.claymore', 'class' => 'application/octet-stream', 'cld' => 'model/vnd.cld', 'clkk' => 'application/vnd.crick.clicker.keyboard', 'clkp' => 'application/vnd.crick.clicker.palette', 'clkt' => 'application/vnd.crick.clicker.template', 'clkw' => 'application/vnd.crick.clicker.wordbank', 'clkx' => 'application/vnd.crick.clicker', 'clp' => 'application/x-msclip', 'cmc' => 'application/vnd.cosmocaller', 'cmdf' => 'chemical/x-cmdf', 'cml' => 'chemical/x-cml', 'cmp' => 'application/vnd.yellowriver-custom-menu', 'cmx' => 'image/x-cmx', 'cod' => 'application/vnd.rim.cod', 'coffee' => 'text/coffeescript', 'com' => 'application/x-msdownload', 'conf' => 'text/plain', 'cpio' => 'application/x-cpio', 'cpl' => 'application/cpl+xml', 'cpp' => 'text/x-c', 'cpt' => 'application/mac-compactpro', 'crd' => 'application/x-mscardfile', 'crl' => 'application/pkix-crl', 'crt' => 'application/x-x509-ca-cert', 'crx' => 'application/x-chrome-extension', 'cryptonote' => 'application/vnd.rig.cryptonote', 'csh' => 'application/x-csh', 'csl' => 'application/vnd.citationstyles.style+xml', 'csml' => 'chemical/x-csml', 'csp' => 'application/vnd.commonspace', 'csr' => 'application/octet-stream', 'css' => 'text/css', 'cst' => 'application/x-director', 'csv' => 'text/csv', 'cu' => 'application/cu-seeme', 'curl' => 'text/vnd.curl', 'cwl' => 'application/cwl', 'cww' => 'application/prs.cww', 'cxt' => 'application/x-director', 'cxx' => 'text/x-c', 'dae' => 'model/vnd.collada+xml', 'daf' => 'application/vnd.mobius.daf', 'dart' => 'application/vnd.dart', 'dataless' => 'application/vnd.fdsn.seed', 'davmount' => 'application/davmount+xml', 'dbf' => 'application/vnd.dbf', 'dbk' => 'application/docbook+xml', 'dcr' => 'application/x-director', 'dcurl' => 'text/vnd.curl.dcurl', 'dd2' => 'application/vnd.oma.dd2+xml', 'ddd' => 'application/vnd.fujixerox.ddd', 'ddf' => 'application/vnd.syncml.dmddf+xml', 'dds' => 'image/vnd.ms-dds', 'deb' => 'application/x-debian-package', 'def' => 'text/plain', 'deploy' => 'application/octet-stream', 'der' => 'application/x-x509-ca-cert', 'dfac' => 'application/vnd.dreamfactory', 'dgc' => 'application/x-dgc-compressed', 'dib' => 'image/bmp', 'dic' => 'text/x-c', 'dir' => 'application/x-director', 'dis' => 'application/vnd.mobius.dis', 'disposition-notification' => 'message/disposition-notification', 'dist' => 'application/octet-stream', 'distz' => 'application/octet-stream', 'djv' => 'image/vnd.djvu', 'djvu' => 'image/vnd.djvu', 'dll' => 'application/octet-stream', 'dmg' => 'application/x-apple-diskimage', 'dmn' => 'application/octet-stream', 'dmp' => 'application/vnd.tcpdump.pcap', 'dms' => 'application/octet-stream', 'dna' => 'application/vnd.dna', 'doc' => 'application/msword', 'docm' => 'application/vnd.ms-word.template.macroEnabled.12', 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'dot' => 'application/msword', 'dotm' => 'application/vnd.ms-word.template.macroEnabled.12', 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', 'dp' => 'application/vnd.osgi.dp', 'dpg' => 'application/vnd.dpgraph', 'dpx' => 'image/dpx', 'dra' => 'audio/vnd.dra', 'drle' => 'image/dicom-rle', 'dsc' => 'text/prs.lines.tag', 'dssc' => 'application/dssc+der', 'dtb' => 'application/x-dtbook+xml', 'dtd' => 'application/xml-dtd', 'dts' => 'audio/vnd.dts', 'dtshd' => 'audio/vnd.dts.hd', 'dump' => 'application/octet-stream', 'dvb' => 'video/vnd.dvb.file', 'dvi' => 'application/x-dvi', 'dwd' => 'application/atsc-dwd+xml', 'dwf' => 'model/vnd.dwf', 'dwg' => 'image/vnd.dwg', 'dxf' => 'image/vnd.dxf', 'dxp' => 'application/vnd.spotfire.dxp', 'dxr' => 'application/x-director', 'ear' => 'application/java-archive', 'ecelp4800' => 'audio/vnd.nuera.ecelp4800', 'ecelp7470' => 'audio/vnd.nuera.ecelp7470', 'ecelp9600' => 'audio/vnd.nuera.ecelp9600', 'ecma' => 'application/ecmascript', 'edm' => 'application/vnd.novadigm.edm', 'edx' => 'application/vnd.novadigm.edx', 'efif' => 'application/vnd.picsel', 'ei6' => 'application/vnd.pg.osasli', 'elc' => 'application/octet-stream', 'emf' => 'image/emf', 'eml' => 'message/rfc822', 'emma' => 'application/emma+xml', 'emotionml' => 'application/emotionml+xml', 'emz' => 'application/x-msmetafile', 'eol' => 'audio/vnd.digital-winds', 'eot' => 'application/vnd.ms-fontobject', 'eps' => 'application/postscript', 'epub' => 'application/epub+zip', 'es3' => 'application/vnd.eszigno3+xml', 'esa' => 'application/vnd.osgi.subsystem', 'esf' => 'application/vnd.epson.esf', 'et3' => 'application/vnd.eszigno3+xml', 'etx' => 'text/x-setext', 'eva' => 'application/x-eva', 'evy' => 'application/x-envoy', 'exe' => 'application/octet-stream', 'exi' => 'application/exi', 'exp' => 'application/express', 'exr' => 'image/aces', 'ext' => 'application/vnd.novadigm.ext', 'ez' => 'application/andrew-inset', 'ez2' => 'application/vnd.ezpix-album', 'ez3' => 'application/vnd.ezpix-package', 'f' => 'text/x-fortran', 'f4v' => 'video/mp4', 'f77' => 'text/x-fortran', 'f90' => 'text/x-fortran', 'fbs' => 'image/vnd.fastbidsheet', 'fcdt' => 'application/vnd.adobe.formscentral.fcdt', 'fcs' => 'application/vnd.isac.fcs', 'fdf' => 'application/vnd.fdf', 'fdt' => 'application/fdt+xml', 'fe_launch' => 'application/vnd.denovo.fcselayout-link', 'fg5' => 'application/vnd.fujitsu.oasysgp', 'fgd' => 'application/x-director', 'fh' => 'image/x-freehand', 'fh4' => 'image/x-freehand', 'fh5' => 'image/x-freehand', 'fh7' => 'image/x-freehand', 'fhc' => 'image/x-freehand', 'fig' => 'application/x-xfig', 'fits' => 'image/fits', 'flac' => 'audio/x-flac', 'fli' => 'video/x-fli', 'flo' => 'application/vnd.micrografx.flo', 'flv' => 'video/x-flv', 'flw' => 'application/vnd.kde.kivio', 'flx' => 'text/vnd.fmi.flexstor', 'fly' => 'text/vnd.fly', 'fm' => 'application/vnd.framemaker', 'fnc' => 'application/vnd.frogans.fnc', 'fo' => 'application/vnd.software602.filler.form+xml', 'for' => 'text/x-fortran', 'fpx' => 'image/vnd.fpx', 'frame' => 'application/vnd.framemaker', 'fsc' => 'application/vnd.fsc.weblaunch', 'fst' => 'image/vnd.fst', 'ftc' => 'application/vnd.fluxtime.clip', 'fti' => 'application/vnd.anser-web-funds-transfer-initiation', 'fvt' => 'video/vnd.fvt', 'fxp' => 'application/vnd.adobe.fxp', 'fxpl' => 'application/vnd.adobe.fxp', 'fzs' => 'application/vnd.fuzzysheet', 'g2w' => 'application/vnd.geoplan', 'g3' => 'image/g3fax', 'g3w' => 'application/vnd.geospace', 'gac' => 'application/vnd.groove-account', 'gam' => 'application/x-tads', 'gbr' => 'application/rpki-ghostbusters', 'gca' => 'application/x-gca-compressed', 'gdl' => 'model/vnd.gdl', 'gdoc' => 'application/vnd.google-apps.document', 'ged' => 'text/vnd.familysearch.gedcom', 'geo' => 'application/vnd.dynageo', 'geojson' => 'application/geo+json', 'gex' => 'application/vnd.geometry-explorer', 'ggb' => 'application/vnd.geogebra.file', 'ggt' => 'application/vnd.geogebra.tool', 'ghf' => 'application/vnd.groove-help', 'gif' => 'image/gif', 'gim' => 'application/vnd.groove-identity-message', 'glb' => 'model/gltf-binary', 'gltf' => 'model/gltf+json', 'gml' => 'application/gml+xml', 'gmx' => 'application/vnd.gmx', 'gnumeric' => 'application/x-gnumeric', 'gpg' => 'application/gpg-keys', 'gph' => 'application/vnd.flographit', 'gpx' => 'application/gpx+xml', 'gqf' => 'application/vnd.grafeq', 'gqs' => 'application/vnd.grafeq', 'gram' => 'application/srgs', 'gramps' => 'application/x-gramps-xml', 'gre' => 'application/vnd.geometry-explorer', 'grv' => 'application/vnd.groove-injector', 'grxml' => 'application/srgs+xml', 'gsf' => 'application/x-font-ghostscript', 'gsheet' => 'application/vnd.google-apps.spreadsheet', 'gslides' => 'application/vnd.google-apps.presentation', 'gtar' => 'application/x-gtar', 'gtm' => 'application/vnd.groove-tool-message', 'gtw' => 'model/vnd.gtw', 'gv' => 'text/vnd.graphviz', 'gxf' => 'application/gxf', 'gxt' => 'application/vnd.geonext', 'gz' => 'application/gzip', 'gzip' => 'application/gzip', 'h' => 'text/x-c', 'h261' => 'video/h261', 'h263' => 'video/h263', 'h264' => 'video/h264', 'hal' => 'application/vnd.hal+xml', 'hbci' => 'application/vnd.hbci', 'hbs' => 'text/x-handlebars-template', 'hdd' => 'application/x-virtualbox-hdd', 'hdf' => 'application/x-hdf', 'heic' => 'image/heic', 'heics' => 'image/heic-sequence', 'heif' => 'image/heif', 'heifs' => 'image/heif-sequence', 'hej2' => 'image/hej2k', 'held' => 'application/atsc-held+xml', 'hh' => 'text/x-c', 'hjson' => 'application/hjson', 'hlp' => 'application/winhlp', 'hpgl' => 'application/vnd.hp-hpgl', 'hpid' => 'application/vnd.hp-hpid', 'hps' => 'application/vnd.hp-hps', 'hqx' => 'application/mac-binhex40', 'hsj2' => 'image/hsj2', 'htc' => 'text/x-component', 'htke' => 'application/vnd.kenameaapp', 'htm' => 'text/html', 'html' => 'text/html', 'hvd' => 'application/vnd.yamaha.hv-dic', 'hvp' => 'application/vnd.yamaha.hv-voice', 'hvs' => 'application/vnd.yamaha.hv-script', 'i2g' => 'application/vnd.intergeo', 'icc' => 'application/vnd.iccprofile', 'ice' => 'x-conference/x-cooltalk', 'icm' => 'application/vnd.iccprofile', 'ico' => 'image/x-icon', 'ics' => 'text/calendar', 'ief' => 'image/ief', 'ifb' => 'text/calendar', 'ifm' => 'application/vnd.shana.informed.formdata', 'iges' => 'model/iges', 'igl' => 'application/vnd.igloader', 'igm' => 'application/vnd.insors.igm', 'igs' => 'model/iges', 'igx' => 'application/vnd.micrografx.igx', 'iif' => 'application/vnd.shana.informed.interchange', 'img' => 'application/octet-stream', 'imp' => 'application/vnd.accpac.simply.imp', 'ims' => 'application/vnd.ms-ims', 'in' => 'text/plain', 'ini' => 'text/plain', 'ink' => 'application/inkml+xml', 'inkml' => 'application/inkml+xml', 'install' => 'application/x-install-instructions', 'iota' => 'application/vnd.astraea-software.iota', 'ipfix' => 'application/ipfix', 'ipk' => 'application/vnd.shana.informed.package', 'irm' => 'application/vnd.ibm.rights-management', 'irp' => 'application/vnd.irepository.package+xml', 'iso' => 'application/x-iso9660-image', 'itp' => 'application/vnd.shana.informed.formtemplate', 'its' => 'application/its+xml', 'ivp' => 'application/vnd.immervision-ivp', 'ivu' => 'application/vnd.immervision-ivu', 'jad' => 'text/vnd.sun.j2me.app-descriptor', 'jade' => 'text/jade', 'jam' => 'application/vnd.jam', 'jar' => 'application/java-archive', 'jardiff' => 'application/x-java-archive-diff', 'java' => 'text/x-java-source', 'jhc' => 'image/jphc', 'jisp' => 'application/vnd.jisp', 'jls' => 'image/jls', 'jlt' => 'application/vnd.hp-jlyt', 'jng' => 'image/x-jng', 'jnlp' => 'application/x-java-jnlp-file', 'joda' => 'application/vnd.joost.joda-archive', 'jp2' => 'image/jp2', 'jpe' => 'image/jpeg', 'jpeg' => 'image/jpeg', 'jpf' => 'image/jpx', 'jpg' => 'image/jpeg', 'jpg2' => 'image/jp2', 'jpgm' => 'video/jpm', 'jpgv' => 'video/jpeg', 'jph' => 'image/jph', 'jpm' => 'video/jpm', 'jpx' => 'image/jpx', 'js' => 'application/javascript', 'json' => 'application/json', 'json5' => 'application/json5', 'jsonld' => 'application/ld+json', 'jsonml' => 'application/jsonml+json', 'jsx' => 'text/jsx', 'jt' => 'model/jt', 'jxr' => 'image/jxr', 'jxra' => 'image/jxra', 'jxrs' => 'image/jxrs', 'jxs' => 'image/jxs', 'jxsc' => 'image/jxsc', 'jxsi' => 'image/jxsi', 'jxss' => 'image/jxss', 'kar' => 'audio/midi', 'karbon' => 'application/vnd.kde.karbon', 'kdb' => 'application/octet-stream', 'kdbx' => 'application/x-keepass2', 'key' => 'application/x-iwork-keynote-sffkey', 'kfo' => 'application/vnd.kde.kformula', 'kia' => 'application/vnd.kidspiration', 'kml' => 'application/vnd.google-earth.kml+xml', 'kmz' => 'application/vnd.google-earth.kmz', 'kne' => 'application/vnd.kinar', 'knp' => 'application/vnd.kinar', 'kon' => 'application/vnd.kde.kontour', 'kpr' => 'application/vnd.kde.kpresenter', 'kpt' => 'application/vnd.kde.kpresenter', 'kpxx' => 'application/vnd.ds-keypoint', 'ksp' => 'application/vnd.kde.kspread', 'ktr' => 'application/vnd.kahootz', 'ktx' => 'image/ktx', 'ktx2' => 'image/ktx2', 'ktz' => 'application/vnd.kahootz', 'kwd' => 'application/vnd.kde.kword', 'kwt' => 'application/vnd.kde.kword', 'lasxml' => 'application/vnd.las.las+xml', 'latex' => 'application/x-latex', 'lbd' => 'application/vnd.llamagraphics.life-balance.desktop', 'lbe' => 'application/vnd.llamagraphics.life-balance.exchange+xml', 'les' => 'application/vnd.hhe.lesson-player', 'less' => 'text/less', 'lgr' => 'application/lgr+xml', 'lha' => 'application/octet-stream', 'link66' => 'application/vnd.route66.link66+xml', 'list' => 'text/plain', 'list3820' => 'application/vnd.ibm.modcap', 'listafp' => 'application/vnd.ibm.modcap', 'litcoffee' => 'text/coffeescript', 'lnk' => 'application/x-ms-shortcut', 'log' => 'text/plain', 'lostxml' => 'application/lost+xml', 'lrf' => 'application/octet-stream', 'lrm' => 'application/vnd.ms-lrm', 'ltf' => 'application/vnd.frogans.ltf', 'lua' => 'text/x-lua', 'luac' => 'application/x-lua-bytecode', 'lvp' => 'audio/vnd.lucent.voice', 'lwp' => 'application/vnd.lotus-wordpro', 'lzh' => 'application/octet-stream', 'm1v' => 'video/mpeg', 'm2a' => 'audio/mpeg', 'm2v' => 'video/mpeg', 'm3a' => 'audio/mpeg', 'm3u' => 'text/plain', 'm3u8' => 'application/vnd.apple.mpegurl', 'm4a' => 'audio/x-m4a', 'm4p' => 'application/mp4', 'm4s' => 'video/iso.segment', 'm4u' => 'application/vnd.mpegurl', 'm4v' => 'video/x-m4v', 'm13' => 'application/x-msmediaview', 'm14' => 'application/x-msmediaview', 'm21' => 'application/mp21', 'ma' => 'application/mathematica', 'mads' => 'application/mads+xml', 'maei' => 'application/mmt-aei+xml', 'mag' => 'application/vnd.ecowin.chart', 'maker' => 'application/vnd.framemaker', 'man' => 'text/troff', 'manifest' => 'text/cache-manifest', 'map' => 'application/json', 'mar' => 'application/octet-stream', 'markdown' => 'text/markdown', 'mathml' => 'application/mathml+xml', 'mb' => 'application/mathematica', 'mbk' => 'application/vnd.mobius.mbk', 'mbox' => 'application/mbox', 'mc1' => 'application/vnd.medcalcdata', 'mcd' => 'application/vnd.mcd', 'mcurl' => 'text/vnd.curl.mcurl', 'md' => 'text/markdown', 'mdb' => 'application/x-msaccess', 'mdi' => 'image/vnd.ms-modi', 'mdx' => 'text/mdx', 'me' => 'text/troff', 'mesh' => 'model/mesh', 'meta4' => 'application/metalink4+xml', 'metalink' => 'application/metalink+xml', 'mets' => 'application/mets+xml', 'mfm' => 'application/vnd.mfmp', 'mft' => 'application/rpki-manifest', 'mgp' => 'application/vnd.osgeo.mapguide.package', 'mgz' => 'application/vnd.proteus.magazine', 'mid' => 'audio/midi', 'midi' => 'audio/midi', 'mie' => 'application/x-mie', 'mif' => 'application/vnd.mif', 'mime' => 'message/rfc822', 'mj2' => 'video/mj2', 'mjp2' => 'video/mj2', 'mjs' => 'text/javascript', 'mk3d' => 'video/x-matroska', 'mka' => 'audio/x-matroska', 'mkd' => 'text/x-markdown', 'mks' => 'video/x-matroska', 'mkv' => 'video/x-matroska', 'mlp' => 'application/vnd.dolby.mlp', 'mmd' => 'application/vnd.chipnuts.karaoke-mmd', 'mmf' => 'application/vnd.smaf', 'mml' => 'text/mathml', 'mmr' => 'image/vnd.fujixerox.edmics-mmr', 'mng' => 'video/x-mng', 'mny' => 'application/x-msmoney', 'mobi' => 'application/x-mobipocket-ebook', 'mods' => 'application/mods+xml', 'mov' => 'video/quicktime', 'movie' => 'video/x-sgi-movie', 'mp2' => 'audio/mpeg', 'mp2a' => 'audio/mpeg', 'mp3' => 'audio/mpeg', 'mp4' => 'video/mp4', 'mp4a' => 'audio/mp4', 'mp4s' => 'application/mp4', 'mp4v' => 'video/mp4', 'mp21' => 'application/mp21', 'mpc' => 'application/vnd.mophun.certificate', 'mpd' => 'application/dash+xml', 'mpe' => 'video/mpeg', 'mpeg' => 'video/mpeg', 'mpf' => 'application/media-policy-dataset+xml', 'mpg' => 'video/mpeg', 'mpg4' => 'video/mp4', 'mpga' => 'audio/mpeg', 'mpkg' => 'application/vnd.apple.installer+xml', 'mpm' => 'application/vnd.blueice.multipass', 'mpn' => 'application/vnd.mophun.application', 'mpp' => 'application/vnd.ms-project', 'mpt' => 'application/vnd.ms-project', 'mpy' => 'application/vnd.ibm.minipay', 'mqy' => 'application/vnd.mobius.mqy', 'mrc' => 'application/marc', 'mrcx' => 'application/marcxml+xml', 'ms' => 'text/troff', 'mscml' => 'application/mediaservercontrol+xml', 'mseed' => 'application/vnd.fdsn.mseed', 'mseq' => 'application/vnd.mseq', 'msf' => 'application/vnd.epson.msf', 'msg' => 'application/vnd.ms-outlook', 'msh' => 'model/mesh', 'msi' => 'application/x-msdownload', 'msix' => 'application/msix', 'msixbundle' => 'application/msixbundle', 'msl' => 'application/vnd.mobius.msl', 'msm' => 'application/octet-stream', 'msp' => 'application/octet-stream', 'msty' => 'application/vnd.muvee.style', 'mtl' => 'model/mtl', 'mts' => 'model/vnd.mts', 'mus' => 'application/vnd.musician', 'musd' => 'application/mmt-usd+xml', 'musicxml' => 'application/vnd.recordare.musicxml+xml', 'mvb' => 'application/x-msmediaview', 'mvt' => 'application/vnd.mapbox-vector-tile', 'mwf' => 'application/vnd.mfer', 'mxf' => 'application/mxf', 'mxl' => 'application/vnd.recordare.musicxml', 'mxmf' => 'audio/mobile-xmf', 'mxml' => 'application/xv+xml', 'mxs' => 'application/vnd.triscape.mxs', 'mxu' => 'video/vnd.mpegurl', 'n-gage' => 'application/vnd.nokia.n-gage.symbian.install', 'n3' => 'text/n3', 'nb' => 'application/mathematica', 'nbp' => 'application/vnd.wolfram.player', 'nc' => 'application/x-netcdf', 'ncx' => 'application/x-dtbncx+xml', 'nfo' => 'text/x-nfo', 'ngdat' => 'application/vnd.nokia.n-gage.data', 'nitf' => 'application/vnd.nitf', 'nlu' => 'application/vnd.neurolanguage.nlu', 'nml' => 'application/vnd.enliven', 'nnd' => 'application/vnd.noblenet-directory', 'nns' => 'application/vnd.noblenet-sealer', 'nnw' => 'application/vnd.noblenet-web', 'npx' => 'image/vnd.net-fpx', 'nq' => 'application/n-quads', 'nsc' => 'application/x-conference', 'nsf' => 'application/vnd.lotus-notes', 'nt' => 'application/n-triples', 'ntf' => 'application/vnd.nitf', 'numbers' => 'application/x-iwork-numbers-sffnumbers', 'nzb' => 'application/x-nzb', 'oa2' => 'application/vnd.fujitsu.oasys2', 'oa3' => 'application/vnd.fujitsu.oasys3', 'oas' => 'application/vnd.fujitsu.oasys', 'obd' => 'application/x-msbinder', 'obgx' => 'application/vnd.openblox.game+xml', 'obj' => 'model/obj', 'oda' => 'application/oda', 'odb' => 'application/vnd.oasis.opendocument.database', 'odc' => 'application/vnd.oasis.opendocument.chart', 'odf' => 'application/vnd.oasis.opendocument.formula', 'odft' => 'application/vnd.oasis.opendocument.formula-template', 'odg' => 'application/vnd.oasis.opendocument.graphics', 'odi' => 'application/vnd.oasis.opendocument.image', 'odm' => 'application/vnd.oasis.opendocument.text-master', 'odp' => 'application/vnd.oasis.opendocument.presentation', 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', 'odt' => 'application/vnd.oasis.opendocument.text', 'oga' => 'audio/ogg', 'ogex' => 'model/vnd.opengex', 'ogg' => 'audio/ogg', 'ogv' => 'video/ogg', 'ogx' => 'application/ogg', 'omdoc' => 'application/omdoc+xml', 'onepkg' => 'application/onenote', 'onetmp' => 'application/onenote', 'onetoc' => 'application/onenote', 'onetoc2' => 'application/onenote', 'opf' => 'application/oebps-package+xml', 'opml' => 'text/x-opml', 'oprc' => 'application/vnd.palm', 'opus' => 'audio/ogg', 'org' => 'text/x-org', 'osf' => 'application/vnd.yamaha.openscoreformat', 'osfpvg' => 'application/vnd.yamaha.openscoreformat.osfpvg+xml', 'osm' => 'application/vnd.openstreetmap.data+xml', 'otc' => 'application/vnd.oasis.opendocument.chart-template', 'otf' => 'font/otf', 'otg' => 'application/vnd.oasis.opendocument.graphics-template', 'oth' => 'application/vnd.oasis.opendocument.text-web', 'oti' => 'application/vnd.oasis.opendocument.image-template', 'otp' => 'application/vnd.oasis.opendocument.presentation-template', 'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template', 'ott' => 'application/vnd.oasis.opendocument.text-template', 'ova' => 'application/x-virtualbox-ova', 'ovf' => 'application/x-virtualbox-ovf', 'owl' => 'application/rdf+xml', 'oxps' => 'application/oxps', 'oxt' => 'application/vnd.openofficeorg.extension', 'p' => 'text/x-pascal', 'p7a' => 'application/x-pkcs7-signature', 'p7b' => 'application/x-pkcs7-certificates', 'p7c' => 'application/pkcs7-mime', 'p7m' => 'application/pkcs7-mime', 'p7r' => 'application/x-pkcs7-certreqresp', 'p7s' => 'application/pkcs7-signature', 'p8' => 'application/pkcs8', 'p10' => 'application/x-pkcs10', 'p12' => 'application/x-pkcs12', 'pac' => 'application/x-ns-proxy-autoconfig', 'pages' => 'application/x-iwork-pages-sffpages', 'pas' => 'text/x-pascal', 'paw' => 'application/vnd.pawaafile', 'pbd' => 'application/vnd.powerbuilder6', 'pbm' => 'image/x-portable-bitmap', 'pcap' => 'application/vnd.tcpdump.pcap', 'pcf' => 'application/x-font-pcf', 'pcl' => 'application/vnd.hp-pcl', 'pclxl' => 'application/vnd.hp-pclxl', 'pct' => 'image/x-pict', 'pcurl' => 'application/vnd.curl.pcurl', 'pcx' => 'image/x-pcx', 'pdb' => 'application/x-pilot', 'pde' => 'text/x-processing', 'pdf' => 'application/pdf', 'pem' => 'application/x-x509-user-cert', 'pfa' => 'application/x-font-type1', 'pfb' => 'application/x-font-type1', 'pfm' => 'application/x-font-type1', 'pfr' => 'application/font-tdpfr', 'pfx' => 'application/x-pkcs12', 'pgm' => 'image/x-portable-graymap', 'pgn' => 'application/x-chess-pgn', 'pgp' => 'application/pgp', 'phar' => 'application/octet-stream', 'php' => 'application/x-httpd-php', 'php3' => 'application/x-httpd-php', 'php4' => 'application/x-httpd-php', 'phps' => 'application/x-httpd-php-source', 'phtml' => 'application/x-httpd-php', 'pic' => 'image/x-pict', 'pkg' => 'application/octet-stream', 'pki' => 'application/pkixcmp', 'pkipath' => 'application/pkix-pkipath', 'pkpass' => 'application/vnd.apple.pkpass', 'pl' => 'application/x-perl', 'plb' => 'application/vnd.3gpp.pic-bw-large', 'plc' => 'application/vnd.mobius.plc', 'plf' => 'application/vnd.pocketlearn', 'pls' => 'application/pls+xml', 'pm' => 'application/x-perl', 'pml' => 'application/vnd.ctc-posml', 'png' => 'image/png', 'pnm' => 'image/x-portable-anymap', 'portpkg' => 'application/vnd.macports.portpkg', 'pot' => 'application/vnd.ms-powerpoint', 'potm' => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12', 'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template', 'ppa' => 'application/vnd.ms-powerpoint', 'ppam' => 'application/vnd.ms-powerpoint.addin.macroEnabled.12', 'ppd' => 'application/vnd.cups-ppd', 'ppm' => 'image/x-portable-pixmap', 'pps' => 'application/vnd.ms-powerpoint', 'ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12', 'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', 'ppt' => 'application/powerpoint', 'pptm' => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12', 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 'pqa' => 'application/vnd.palm', 'prc' => 'model/prc', 'pre' => 'application/vnd.lotus-freelance', 'prf' => 'application/pics-rules', 'provx' => 'application/provenance+xml', 'ps' => 'application/postscript', 'psb' => 'application/vnd.3gpp.pic-bw-small', 'psd' => 'application/x-photoshop', 'psf' => 'application/x-font-linux-psf', 'pskcxml' => 'application/pskc+xml', 'pti' => 'image/prs.pti', 'ptid' => 'application/vnd.pvi.ptid1', 'pub' => 'application/x-mspublisher', 'pvb' => 'application/vnd.3gpp.pic-bw-var', 'pwn' => 'application/vnd.3m.post-it-notes', 'pya' => 'audio/vnd.ms-playready.media.pya', 'pyo' => 'model/vnd.pytha.pyox', 'pyox' => 'model/vnd.pytha.pyox', 'pyv' => 'video/vnd.ms-playready.media.pyv', 'qam' => 'application/vnd.epson.quickanime', 'qbo' => 'application/vnd.intu.qbo', 'qfx' => 'application/vnd.intu.qfx', 'qps' => 'application/vnd.publishare-delta-tree', 'qt' => 'video/quicktime', 'qwd' => 'application/vnd.quark.quarkxpress', 'qwt' => 'application/vnd.quark.quarkxpress', 'qxb' => 'application/vnd.quark.quarkxpress', 'qxd' => 'application/vnd.quark.quarkxpress', 'qxl' => 'application/vnd.quark.quarkxpress', 'qxt' => 'application/vnd.quark.quarkxpress', 'ra' => 'audio/x-realaudio', 'ram' => 'audio/x-pn-realaudio', 'raml' => 'application/raml+yaml', 'rapd' => 'application/route-apd+xml', 'rar' => 'application/x-rar', 'ras' => 'image/x-cmu-raster', 'rcprofile' => 'application/vnd.ipunplugged.rcprofile', 'rdf' => 'application/rdf+xml', 'rdz' => 'application/vnd.data-vision.rdz', 'relo' => 'application/p2p-overlay+xml', 'rep' => 'application/vnd.businessobjects', 'res' => 'application/x-dtbresource+xml', 'rgb' => 'image/x-rgb', 'rif' => 'application/reginfo+xml', 'rip' => 'audio/vnd.rip', 'ris' => 'application/x-research-info-systems', 'rl' => 'application/resource-lists+xml', 'rlc' => 'image/vnd.fujixerox.edmics-rlc', 'rld' => 'application/resource-lists-diff+xml', 'rm' => 'audio/x-pn-realaudio', 'rmi' => 'audio/midi', 'rmp' => 'audio/x-pn-realaudio-plugin', 'rms' => 'application/vnd.jcp.javame.midlet-rms', 'rmvb' => 'application/vnd.rn-realmedia-vbr', 'rnc' => 'application/relax-ng-compact-syntax', 'rng' => 'application/xml', 'roa' => 'application/rpki-roa', 'roff' => 'text/troff', 'rp9' => 'application/vnd.cloanto.rp9', 'rpm' => 'audio/x-pn-realaudio-plugin', 'rpss' => 'application/vnd.nokia.radio-presets', 'rpst' => 'application/vnd.nokia.radio-preset', 'rq' => 'application/sparql-query', 'rs' => 'application/rls-services+xml', 'rsa' => 'application/x-pkcs7', 'rsat' => 'application/atsc-rsat+xml', 'rsd' => 'application/rsd+xml', 'rsheet' => 'application/urc-ressheet+xml', 'rss' => 'application/rss+xml', 'rtf' => 'text/rtf', 'rtx' => 'text/richtext', 'run' => 'application/x-makeself', 'rusd' => 'application/route-usd+xml', 'rv' => 'video/vnd.rn-realvideo', 's' => 'text/x-asm', 's3m' => 'audio/s3m', 'saf' => 'application/vnd.yamaha.smaf-audio', 'sass' => 'text/x-sass', 'sbml' => 'application/sbml+xml', 'sc' => 'application/vnd.ibm.secure-container', 'scd' => 'application/x-msschedule', 'scm' => 'application/vnd.lotus-screencam', 'scq' => 'application/scvp-cv-request', 'scs' => 'application/scvp-cv-response', 'scss' => 'text/x-scss', 'scurl' => 'text/vnd.curl.scurl', 'sda' => 'application/vnd.stardivision.draw', 'sdc' => 'application/vnd.stardivision.calc', 'sdd' => 'application/vnd.stardivision.impress', 'sdkd' => 'application/vnd.solent.sdkm+xml', 'sdkm' => 'application/vnd.solent.sdkm+xml', 'sdp' => 'application/sdp', 'sdw' => 'application/vnd.stardivision.writer', 'sea' => 'application/octet-stream', 'see' => 'application/vnd.seemail', 'seed' => 'application/vnd.fdsn.seed', 'sema' => 'application/vnd.sema', 'semd' => 'application/vnd.semd', 'semf' => 'application/vnd.semf', 'senmlx' => 'application/senml+xml', 'sensmlx' => 'application/sensml+xml', 'ser' => 'application/java-serialized-object', 'setpay' => 'application/set-payment-initiation', 'setreg' => 'application/set-registration-initiation', 'sfd-hdstx' => 'application/vnd.hydrostatix.sof-data', 'sfs' => 'application/vnd.spotfire.sfs', 'sfv' => 'text/x-sfv', 'sgi' => 'image/sgi', 'sgl' => 'application/vnd.stardivision.writer-global', 'sgm' => 'text/sgml', 'sgml' => 'text/sgml', 'sh' => 'application/x-sh', 'shar' => 'application/x-shar', 'shex' => 'text/shex', 'shf' => 'application/shf+xml', 'shtml' => 'text/html', 'sid' => 'image/x-mrsid-image', 'sieve' => 'application/sieve', 'sig' => 'application/pgp-signature', 'sil' => 'audio/silk', 'silo' => 'model/mesh', 'sis' => 'application/vnd.symbian.install', 'sisx' => 'application/vnd.symbian.install', 'sit' => 'application/x-stuffit', 'sitx' => 'application/x-stuffitx', 'siv' => 'application/sieve', 'skd' => 'application/vnd.koan', 'skm' => 'application/vnd.koan', 'skp' => 'application/vnd.koan', 'skt' => 'application/vnd.koan', 'sldm' => 'application/vnd.ms-powerpoint.slide.macroenabled.12', 'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide', 'slim' => 'text/slim', 'slm' => 'text/slim', 'sls' => 'application/route-s-tsid+xml', 'slt' => 'application/vnd.epson.salt', 'sm' => 'application/vnd.stepmania.stepchart', 'smf' => 'application/vnd.stardivision.math', 'smi' => 'application/smil', 'smil' => 'application/smil', 'smv' => 'video/x-smv', 'smzip' => 'application/vnd.stepmania.package', 'snd' => 'audio/basic', 'snf' => 'application/x-font-snf', 'so' => 'application/octet-stream', 'spc' => 'application/x-pkcs7-certificates', 'spdx' => 'text/spdx', 'spf' => 'application/vnd.yamaha.smaf-phrase', 'spl' => 'application/x-futuresplash', 'spot' => 'text/vnd.in3d.spot', 'spp' => 'application/scvp-vp-response', 'spq' => 'application/scvp-vp-request', 'spx' => 'audio/ogg', 'sql' => 'application/x-sql', 'src' => 'application/x-wais-source', 'srt' => 'application/x-subrip', 'sru' => 'application/sru+xml', 'srx' => 'application/sparql-results+xml', 'ssdl' => 'application/ssdl+xml', 'sse' => 'application/vnd.kodak-descriptor', 'ssf' => 'application/vnd.epson.ssf', 'ssml' => 'application/ssml+xml', 'sst' => 'application/octet-stream', 'st' => 'application/vnd.sailingtracker.track', 'stc' => 'application/vnd.sun.xml.calc.template', 'std' => 'application/vnd.sun.xml.draw.template', 'step' => 'application/STEP', 'stf' => 'application/vnd.wt.stf', 'sti' => 'application/vnd.sun.xml.impress.template', 'stk' => 'application/hyperstudio', 'stl' => 'model/stl', 'stp' => 'application/STEP', 'stpx' => 'model/step+xml', 'stpxz' => 'model/step-xml+zip', 'stpz' => 'model/step+zip', 'str' => 'application/vnd.pg.format', 'stw' => 'application/vnd.sun.xml.writer.template', 'styl' => 'text/stylus', 'stylus' => 'text/stylus', 'sub' => 'text/vnd.dvb.subtitle', 'sus' => 'application/vnd.sus-calendar', 'susp' => 'application/vnd.sus-calendar', 'sv4cpio' => 'application/x-sv4cpio', 'sv4crc' => 'application/x-sv4crc', 'svc' => 'application/vnd.dvb.service', 'svd' => 'application/vnd.svd', 'svg' => 'image/svg+xml', 'svgz' => 'image/svg+xml', 'swa' => 'application/x-director', 'swf' => 'application/x-shockwave-flash', 'swi' => 'application/vnd.aristanetworks.swi', 'swidtag' => 'application/swid+xml', 'sxc' => 'application/vnd.sun.xml.calc', 'sxd' => 'application/vnd.sun.xml.draw', 'sxg' => 'application/vnd.sun.xml.writer.global', 'sxi' => 'application/vnd.sun.xml.impress', 'sxm' => 'application/vnd.sun.xml.math', 'sxw' => 'application/vnd.sun.xml.writer', 't' => 'text/troff', 't3' => 'application/x-t3vm-image', 't38' => 'image/t38', 'taglet' => 'application/vnd.mynfc', 'tao' => 'application/vnd.tao.intent-module-archive', 'tap' => 'image/vnd.tencent.tap', 'tar' => 'application/x-tar', 'tcap' => 'application/vnd.3gpp2.tcap', 'tcl' => 'application/x-tcl', 'td' => 'application/urc-targetdesc+xml', 'teacher' => 'application/vnd.smart.teacher', 'tei' => 'application/tei+xml', 'teicorpus' => 'application/tei+xml', 'tex' => 'application/x-tex', 'texi' => 'application/x-texinfo', 'texinfo' => 'application/x-texinfo', 'text' => 'text/plain', 'tfi' => 'application/thraud+xml', 'tfm' => 'application/x-tex-tfm', 'tfx' => 'image/tiff-fx', 'tga' => 'image/x-tga', 'tgz' => 'application/x-tar', 'thmx' => 'application/vnd.ms-officetheme', 'tif' => 'image/tiff', 'tiff' => 'image/tiff', 'tk' => 'application/x-tcl', 'tmo' => 'application/vnd.tmobile-livetv', 'toml' => 'application/toml', 'torrent' => 'application/x-bittorrent', 'tpl' => 'application/vnd.groove-tool-template', 'tpt' => 'application/vnd.trid.tpt', 'tr' => 'text/troff', 'tra' => 'application/vnd.trueapp', 'trig' => 'application/trig', 'trm' => 'application/x-msterminal', 'ts' => 'video/mp2t', 'tsd' => 'application/timestamped-data', 'tsv' => 'text/tab-separated-values', 'ttc' => 'font/collection', 'ttf' => 'font/ttf', 'ttl' => 'text/turtle', 'ttml' => 'application/ttml+xml', 'twd' => 'application/vnd.simtech-mindmapper', 'twds' => 'application/vnd.simtech-mindmapper', 'txd' => 'application/vnd.genomatix.tuxedo', 'txf' => 'application/vnd.mobius.txf', 'txt' => 'text/plain', 'u3d' => 'model/u3d', 'u8dsn' => 'message/global-delivery-status', 'u8hdr' => 'message/global-headers', 'u8mdn' => 'message/global-disposition-notification', 'u8msg' => 'message/global', 'u32' => 'application/x-authorware-bin', 'ubj' => 'application/ubjson', 'udeb' => 'application/x-debian-package', 'ufd' => 'application/vnd.ufdl', 'ufdl' => 'application/vnd.ufdl', 'ulx' => 'application/x-glulx', 'umj' => 'application/vnd.umajin', 'unityweb' => 'application/vnd.unity', 'uo' => 'application/vnd.uoml+xml', 'uoml' => 'application/vnd.uoml+xml', 'uri' => 'text/uri-list', 'uris' => 'text/uri-list', 'urls' => 'text/uri-list', 'usda' => 'model/vnd.usda', 'usdz' => 'model/vnd.usdz+zip', 'ustar' => 'application/x-ustar', 'utz' => 'application/vnd.uiq.theme', 'uu' => 'text/x-uuencode', 'uva' => 'audio/vnd.dece.audio', 'uvd' => 'application/vnd.dece.data', 'uvf' => 'application/vnd.dece.data', 'uvg' => 'image/vnd.dece.graphic', 'uvh' => 'video/vnd.dece.hd', 'uvi' => 'image/vnd.dece.graphic', 'uvm' => 'video/vnd.dece.mobile', 'uvp' => 'video/vnd.dece.pd', 'uvs' => 'video/vnd.dece.sd', 'uvt' => 'application/vnd.dece.ttml+xml', 'uvu' => 'video/vnd.uvvu.mp4', 'uvv' => 'video/vnd.dece.video', 'uvva' => 'audio/vnd.dece.audio', 'uvvd' => 'application/vnd.dece.data', 'uvvf' => 'application/vnd.dece.data', 'uvvg' => 'image/vnd.dece.graphic', 'uvvh' => 'video/vnd.dece.hd', 'uvvi' => 'image/vnd.dece.graphic', 'uvvm' => 'video/vnd.dece.mobile', 'uvvp' => 'video/vnd.dece.pd', 'uvvs' => 'video/vnd.dece.sd', 'uvvt' => 'application/vnd.dece.ttml+xml', 'uvvu' => 'video/vnd.uvvu.mp4', 'uvvv' => 'video/vnd.dece.video', 'uvvx' => 'application/vnd.dece.unspecified', 'uvvz' => 'application/vnd.dece.zip', 'uvx' => 'application/vnd.dece.unspecified', 'uvz' => 'application/vnd.dece.zip', 'vbox' => 'application/x-virtualbox-vbox', 'vbox-extpack' => 'application/x-virtualbox-vbox-extpack', 'vcard' => 'text/vcard', 'vcd' => 'application/x-cdlink', 'vcf' => 'text/x-vcard', 'vcg' => 'application/vnd.groove-vcard', 'vcs' => 'text/x-vcalendar', 'vcx' => 'application/vnd.vcx', 'vdi' => 'application/x-virtualbox-vdi', 'vds' => 'model/vnd.sap.vds', 'vhd' => 'application/x-virtualbox-vhd', 'vis' => 'application/vnd.visionary', 'viv' => 'video/vnd.vivo', 'vlc' => 'application/videolan', 'vmdk' => 'application/x-virtualbox-vmdk', 'vob' => 'video/x-ms-vob', 'vor' => 'application/vnd.stardivision.writer', 'vox' => 'application/x-authorware-bin', 'vrml' => 'model/vrml', 'vsd' => 'application/vnd.visio', 'vsf' => 'application/vnd.vsf', 'vss' => 'application/vnd.visio', 'vst' => 'application/vnd.visio', 'vsw' => 'application/vnd.visio', 'vtf' => 'image/vnd.valve.source.texture', 'vtt' => 'text/vtt', 'vtu' => 'model/vnd.vtu', 'vxml' => 'application/voicexml+xml', 'w3d' => 'application/x-director', 'wad' => 'application/x-doom', 'wadl' => 'application/vnd.sun.wadl+xml', 'war' => 'application/java-archive', 'wasm' => 'application/wasm', 'wav' => 'audio/x-wav', 'wax' => 'audio/x-ms-wax', 'wbmp' => 'image/vnd.wap.wbmp', 'wbs' => 'application/vnd.criticaltools.wbs+xml', 'wbxml' => 'application/wbxml', 'wcm' => 'application/vnd.ms-works', 'wdb' => 'application/vnd.ms-works', 'wdp' => 'image/vnd.ms-photo', 'weba' => 'audio/webm', 'webapp' => 'application/x-web-app-manifest+json', 'webm' => 'video/webm', 'webmanifest' => 'application/manifest+json', 'webp' => 'image/webp', 'wg' => 'application/vnd.pmi.widget', 'wgsl' => 'text/wgsl', 'wgt' => 'application/widget', 'wif' => 'application/watcherinfo+xml', 'wks' => 'application/vnd.ms-works', 'wm' => 'video/x-ms-wm', 'wma' => 'audio/x-ms-wma', 'wmd' => 'application/x-ms-wmd', 'wmf' => 'image/wmf', 'wml' => 'text/vnd.wap.wml', 'wmlc' => 'application/wmlc', 'wmls' => 'text/vnd.wap.wmlscript', 'wmlsc' => 'application/vnd.wap.wmlscriptc', 'wmv' => 'video/x-ms-wmv', 'wmx' => 'video/x-ms-wmx', 'wmz' => 'application/x-msmetafile', 'woff' => 'font/woff', 'woff2' => 'font/woff2', 'word' => 'application/msword', 'wpd' => 'application/vnd.wordperfect', 'wpl' => 'application/vnd.ms-wpl', 'wps' => 'application/vnd.ms-works', 'wqd' => 'application/vnd.wqd', 'wri' => 'application/x-mswrite', 'wrl' => 'model/vrml', 'wsc' => 'message/vnd.wfa.wsc', 'wsdl' => 'application/wsdl+xml', 'wspolicy' => 'application/wspolicy+xml', 'wtb' => 'application/vnd.webturbo', 'wvx' => 'video/x-ms-wvx', 'x3d' => 'model/x3d+xml', 'x3db' => 'model/x3d+fastinfoset', 'x3dbz' => 'model/x3d+binary', 'x3dv' => 'model/x3d-vrml', 'x3dvz' => 'model/x3d+vrml', 'x3dz' => 'model/x3d+xml', 'x32' => 'application/x-authorware-bin', 'x_b' => 'model/vnd.parasolid.transmit.binary', 'x_t' => 'model/vnd.parasolid.transmit.text', 'xaml' => 'application/xaml+xml', 'xap' => 'application/x-silverlight-app', 'xar' => 'application/vnd.xara', 'xav' => 'application/xcap-att+xml', 'xbap' => 'application/x-ms-xbap', 'xbd' => 'application/vnd.fujixerox.docuworks.binder', 'xbm' => 'image/x-xbitmap', 'xca' => 'application/xcap-caps+xml', 'xcs' => 'application/calendar+xml', 'xdf' => 'application/xcap-diff+xml', 'xdm' => 'application/vnd.syncml.dm+xml', 'xdp' => 'application/vnd.adobe.xdp+xml', 'xdssc' => 'application/dssc+xml', 'xdw' => 'application/vnd.fujixerox.docuworks', 'xel' => 'application/xcap-el+xml', 'xenc' => 'application/xenc+xml', 'xer' => 'application/patch-ops-error+xml', 'xfdf' => 'application/xfdf', 'xfdl' => 'application/vnd.xfdl', 'xht' => 'application/xhtml+xml', 'xhtm' => 'application/vnd.pwg-xhtml-print+xml', 'xhtml' => 'application/xhtml+xml', 'xhvml' => 'application/xv+xml', 'xif' => 'image/vnd.xiff', 'xl' => 'application/excel', 'xla' => 'application/vnd.ms-excel', 'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12', 'xlc' => 'application/vnd.ms-excel', 'xlf' => 'application/xliff+xml', 'xlm' => 'application/vnd.ms-excel', 'xls' => 'application/vnd.ms-excel', 'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12', 'xlsm' => 'application/vnd.ms-excel.sheet.macroEnabled.12', 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'xlt' => 'application/vnd.ms-excel', 'xltm' => 'application/vnd.ms-excel.template.macroEnabled.12', 'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template', 'xlw' => 'application/vnd.ms-excel', 'xm' => 'audio/xm', 'xml' => 'application/xml', 'xns' => 'application/xcap-ns+xml', 'xo' => 'application/vnd.olpc-sugar', 'xop' => 'application/xop+xml', 'xpi' => 'application/x-xpinstall', 'xpl' => 'application/xproc+xml', 'xpm' => 'image/x-xpixmap', 'xpr' => 'application/vnd.is-xpr', 'xps' => 'application/vnd.ms-xpsdocument', 'xpw' => 'application/vnd.intercon.formnet', 'xpx' => 'application/vnd.intercon.formnet', 'xsd' => 'application/xml', 'xsf' => 'application/prs.xsf+xml', 'xsl' => 'application/xml', 'xslt' => 'application/xslt+xml', 'xsm' => 'application/vnd.syncml+xml', 'xspf' => 'application/xspf+xml', 'xul' => 'application/vnd.mozilla.xul+xml', 'xvm' => 'application/xv+xml', 'xvml' => 'application/xv+xml', 'xwd' => 'image/x-xwindowdump', 'xyz' => 'chemical/x-xyz', 'xz' => 'application/x-xz', 'yaml' => 'text/yaml', 'yang' => 'application/yang', 'yin' => 'application/yin+xml', 'yml' => 'text/yaml', 'ymp' => 'text/x-suse-ymp', 'z' => 'application/x-compress', 'z1' => 'application/x-zmachine', 'z2' => 'application/x-zmachine', 'z3' => 'application/x-zmachine', 'z4' => 'application/x-zmachine', 'z5' => 'application/x-zmachine', 'z6' => 'application/x-zmachine', 'z7' => 'application/x-zmachine', 'z8' => 'application/x-zmachine', 'zaz' => 'application/vnd.zzazz.deck+xml', 'zip' => 'application/zip', 'zir' => 'application/vnd.zul', 'zirz' => 'application/vnd.zul', 'zmm' => 'application/vnd.handheld-entertainment+xml', 'zsh' => 'text/x-scriptzsh'];
+ /**
+ * Determines the mimetype of a file by looking at its extension.
+ *
+ * @see https://raw.githubusercontent.com/jshttp/mime-db/master/db.json
+ */
+ public static function fromFilename(string $filename) : ?string
+ {
+ return self::fromExtension(\pathinfo($filename, \PATHINFO_EXTENSION));
+ }
+ /**
+ * Maps a file extensions to a mimetype.
+ *
+ * @see https://raw.githubusercontent.com/jshttp/mime-db/master/db.json
+ */
+ public static function fromExtension(string $extension) : ?string
+ {
+ return self::MIME_TYPES[\strtolower($extension)] ?? null;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/MultipartStream.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/MultipartStream.php
new file mode 100755
index 00000000..49213fca
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/MultipartStream.php
@@ -0,0 +1,130 @@
+boundary = $boundary ?: \bin2hex(\random_bytes(20));
+ $this->stream = $this->createStream($elements);
+ }
+ public function getBoundary() : string
+ {
+ return $this->boundary;
+ }
+ public function isWritable() : bool
+ {
+ return \false;
+ }
+ /**
+ * Get the headers needed before transferring the content of a POST file
+ *
+ * @param string[] $headers
+ */
+ private function getHeaders(array $headers) : string
+ {
+ $str = '';
+ foreach ($headers as $key => $value) {
+ $str .= "{$key}: {$value}\r\n";
+ }
+ return "--{$this->boundary}\r\n" . \trim($str) . "\r\n\r\n";
+ }
+ /**
+ * Create the aggregate stream that will be used to upload the POST data
+ */
+ protected function createStream(array $elements = []) : StreamInterface
+ {
+ $stream = new AppendStream();
+ foreach ($elements as $element) {
+ if (!\is_array($element)) {
+ throw new \UnexpectedValueException('An array is expected');
+ }
+ $this->addElement($stream, $element);
+ }
+ // Add the trailing boundary with CRLF
+ $stream->addStream(Utils::streamFor("--{$this->boundary}--\r\n"));
+ return $stream;
+ }
+ private function addElement(AppendStream $stream, array $element) : void
+ {
+ foreach (['contents', 'name'] as $key) {
+ if (!\array_key_exists($key, $element)) {
+ throw new \InvalidArgumentException("A '{$key}' key is required");
+ }
+ }
+ $element['contents'] = Utils::streamFor($element['contents']);
+ if (empty($element['filename'])) {
+ $uri = $element['contents']->getMetadata('uri');
+ if ($uri && \is_string($uri) && \substr($uri, 0, 6) !== 'php://' && \substr($uri, 0, 7) !== 'data://') {
+ $element['filename'] = $uri;
+ }
+ }
+ [$body, $headers] = $this->createElement($element['name'], $element['contents'], $element['filename'] ?? null, $element['headers'] ?? []);
+ $stream->addStream(Utils::streamFor($this->getHeaders($headers)));
+ $stream->addStream($body);
+ $stream->addStream(Utils::streamFor("\r\n"));
+ }
+ /**
+ * @param string[] $headers
+ *
+ * @return array{0: StreamInterface, 1: string[]}
+ */
+ private function createElement(string $name, StreamInterface $stream, ?string $filename, array $headers) : array
+ {
+ // Set a default content-disposition header if one was no provided
+ $disposition = self::getHeader($headers, 'content-disposition');
+ if (!$disposition) {
+ $headers['Content-Disposition'] = $filename === '0' || $filename ? \sprintf('form-data; name="%s"; filename="%s"', $name, \basename($filename)) : "form-data; name=\"{$name}\"";
+ }
+ // Set a default content-length header if one was no provided
+ $length = self::getHeader($headers, 'content-length');
+ if (!$length) {
+ if ($length = $stream->getSize()) {
+ $headers['Content-Length'] = (string) $length;
+ }
+ }
+ // Set a default Content-Type if one was not supplied
+ $type = self::getHeader($headers, 'content-type');
+ if (!$type && ($filename === '0' || $filename)) {
+ $headers['Content-Type'] = MimeType::fromFilename($filename) ?? 'application/octet-stream';
+ }
+ return [$stream, $headers];
+ }
+ /**
+ * @param string[] $headers
+ */
+ private static function getHeader(array $headers, string $key) : ?string
+ {
+ $lowercaseHeader = \strtolower($key);
+ foreach ($headers as $k => $v) {
+ if (\strtolower((string) $k) === $lowercaseHeader) {
+ return $v;
+ }
+ }
+ return null;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/NoSeekStream.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/NoSeekStream.php
new file mode 100755
index 00000000..106eb734
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/NoSeekStream.php
@@ -0,0 +1,23 @@
+source = $source;
+ $this->size = $options['size'] ?? null;
+ $this->metadata = $options['metadata'] ?? [];
+ $this->buffer = new BufferStream();
+ }
+ public function __toString() : string
+ {
+ try {
+ return Utils::copyToString($this);
+ } catch (\Throwable $e) {
+ if (\PHP_VERSION_ID >= 70400) {
+ throw $e;
+ }
+ \trigger_error(\sprintf('%s::__toString exception: %s', self::class, (string) $e), \E_USER_ERROR);
+ return '';
+ }
+ }
+ public function close() : void
+ {
+ $this->detach();
+ }
+ public function detach()
+ {
+ $this->tellPos = 0;
+ $this->source = null;
+ return null;
+ }
+ public function getSize() : ?int
+ {
+ return $this->size;
+ }
+ public function tell() : int
+ {
+ return $this->tellPos;
+ }
+ public function eof() : bool
+ {
+ return $this->source === null;
+ }
+ public function isSeekable() : bool
+ {
+ return \false;
+ }
+ public function rewind() : void
+ {
+ $this->seek(0);
+ }
+ public function seek($offset, $whence = \SEEK_SET) : void
+ {
+ throw new \RuntimeException('Cannot seek a PumpStream');
+ }
+ public function isWritable() : bool
+ {
+ return \false;
+ }
+ public function write($string) : int
+ {
+ throw new \RuntimeException('Cannot write to a PumpStream');
+ }
+ public function isReadable() : bool
+ {
+ return \true;
+ }
+ public function read($length) : string
+ {
+ $data = $this->buffer->read($length);
+ $readLen = \strlen($data);
+ $this->tellPos += $readLen;
+ $remaining = $length - $readLen;
+ if ($remaining) {
+ $this->pump($remaining);
+ $data .= $this->buffer->read($remaining);
+ $this->tellPos += \strlen($data) - $readLen;
+ }
+ return $data;
+ }
+ public function getContents() : string
+ {
+ $result = '';
+ while (!$this->eof()) {
+ $result .= $this->read(1000000);
+ }
+ return $result;
+ }
+ /**
+ * @return mixed
+ */
+ public function getMetadata($key = null)
+ {
+ if (!$key) {
+ return $this->metadata;
+ }
+ return $this->metadata[$key] ?? null;
+ }
+ private function pump(int $length) : void
+ {
+ if ($this->source !== null) {
+ do {
+ $data = ($this->source)($length);
+ if ($data === \false || $data === null) {
+ $this->source = null;
+ return;
+ }
+ $this->buffer->write($data);
+ $length -= \strlen($data);
+ } while ($length > 0);
+ }
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/Query.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/Query.php
new file mode 100755
index 00000000..e904892a
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/Query.php
@@ -0,0 +1,112 @@
+ '1', 'foo[b]' => '2'])`.
+ *
+ * @param string $str Query string to parse
+ * @param int|bool $urlEncoding How the query string is encoded
+ */
+ public static function parse(string $str, $urlEncoding = \true) : array
+ {
+ $result = [];
+ if ($str === '') {
+ return $result;
+ }
+ if ($urlEncoding === \true) {
+ $decoder = function ($value) {
+ return \rawurldecode(\str_replace('+', ' ', (string) $value));
+ };
+ } elseif ($urlEncoding === \PHP_QUERY_RFC3986) {
+ $decoder = 'rawurldecode';
+ } elseif ($urlEncoding === \PHP_QUERY_RFC1738) {
+ $decoder = 'urldecode';
+ } else {
+ $decoder = function ($str) {
+ return $str;
+ };
+ }
+ foreach (\explode('&', $str) as $kvp) {
+ $parts = \explode('=', $kvp, 2);
+ $key = $decoder($parts[0]);
+ $value = isset($parts[1]) ? $decoder($parts[1]) : null;
+ if (!\array_key_exists($key, $result)) {
+ $result[$key] = $value;
+ } else {
+ if (!\is_array($result[$key])) {
+ $result[$key] = [$result[$key]];
+ }
+ $result[$key][] = $value;
+ }
+ }
+ return $result;
+ }
+ /**
+ * Build a query string from an array of key value pairs.
+ *
+ * This function can use the return value of `parse()` to build a query
+ * string. This function does not modify the provided keys when an array is
+ * encountered (like `http_build_query()` would).
+ *
+ * @param array $params Query string parameters.
+ * @param int|false $encoding Set to false to not encode,
+ * PHP_QUERY_RFC3986 to encode using
+ * RFC3986, or PHP_QUERY_RFC1738 to
+ * encode using RFC1738.
+ * @param bool $treatBoolsAsInts Set to true to encode as 0/1, and
+ * false as false/true.
+ */
+ public static function build(array $params, $encoding = \PHP_QUERY_RFC3986, bool $treatBoolsAsInts = \true) : string
+ {
+ if (!$params) {
+ return '';
+ }
+ if ($encoding === \false) {
+ $encoder = function (string $str) : string {
+ return $str;
+ };
+ } elseif ($encoding === \PHP_QUERY_RFC3986) {
+ $encoder = 'rawurlencode';
+ } elseif ($encoding === \PHP_QUERY_RFC1738) {
+ $encoder = 'urlencode';
+ } else {
+ throw new \InvalidArgumentException('Invalid type');
+ }
+ $castBool = $treatBoolsAsInts ? static function ($v) {
+ return (int) $v;
+ } : static function ($v) {
+ return $v ? 'true' : 'false';
+ };
+ $qs = '';
+ foreach ($params as $k => $v) {
+ $k = $encoder((string) $k);
+ if (!\is_array($v)) {
+ $qs .= $k;
+ $v = \is_bool($v) ? $castBool($v) : $v;
+ if ($v !== null) {
+ $qs .= '=' . $encoder((string) $v);
+ }
+ $qs .= '&';
+ } else {
+ foreach ($v as $vv) {
+ $qs .= $k;
+ $vv = \is_bool($vv) ? $castBool($vv) : $vv;
+ if ($vv !== null) {
+ $qs .= '=' . $encoder((string) $vv);
+ }
+ $qs .= '&';
+ }
+ }
+ }
+ return $qs ? (string) \substr($qs, 0, -1) : '';
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/Request.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/Request.php
new file mode 100755
index 00000000..7627640b
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/Request.php
@@ -0,0 +1,124 @@
+assertMethod($method);
+ if (!$uri instanceof UriInterface) {
+ $uri = new Uri($uri);
+ }
+ $this->method = \strtoupper($method);
+ $this->uri = $uri;
+ $this->setHeaders($headers);
+ $this->protocol = $version;
+ if (!isset($this->headerNames['host'])) {
+ $this->updateHostFromUri();
+ }
+ if ($body !== '' && $body !== null) {
+ $this->stream = Utils::streamFor($body);
+ }
+ }
+ public function getRequestTarget() : string
+ {
+ if ($this->requestTarget !== null) {
+ return $this->requestTarget;
+ }
+ $target = $this->uri->getPath();
+ if ($target === '') {
+ $target = '/';
+ }
+ if ($this->uri->getQuery() != '') {
+ $target .= '?' . $this->uri->getQuery();
+ }
+ return $target;
+ }
+ public function withRequestTarget($requestTarget) : RequestInterface
+ {
+ if (\preg_match('#\\s#', $requestTarget)) {
+ throw new InvalidArgumentException('Invalid request target provided; cannot contain whitespace');
+ }
+ $new = clone $this;
+ $new->requestTarget = $requestTarget;
+ return $new;
+ }
+ public function getMethod() : string
+ {
+ return $this->method;
+ }
+ public function withMethod($method) : RequestInterface
+ {
+ $this->assertMethod($method);
+ $new = clone $this;
+ $new->method = \strtoupper($method);
+ return $new;
+ }
+ public function getUri() : UriInterface
+ {
+ return $this->uri;
+ }
+ public function withUri(UriInterface $uri, $preserveHost = \false) : RequestInterface
+ {
+ if ($uri === $this->uri) {
+ return $this;
+ }
+ $new = clone $this;
+ $new->uri = $uri;
+ if (!$preserveHost || !isset($this->headerNames['host'])) {
+ $new->updateHostFromUri();
+ }
+ return $new;
+ }
+ private function updateHostFromUri() : void
+ {
+ $host = $this->uri->getHost();
+ if ($host == '') {
+ return;
+ }
+ if (($port = $this->uri->getPort()) !== null) {
+ $host .= ':' . $port;
+ }
+ if (isset($this->headerNames['host'])) {
+ $header = $this->headerNames['host'];
+ } else {
+ $header = 'Host';
+ $this->headerNames['host'] = 'Host';
+ }
+ // Ensure Host is the first header.
+ // See: https://datatracker.ietf.org/doc/html/rfc7230#section-5.4
+ $this->headers = [$header => [$host]] + $this->headers;
+ }
+ /**
+ * @param mixed $method
+ */
+ private function assertMethod($method) : void
+ {
+ if (!\is_string($method) || $method === '') {
+ throw new InvalidArgumentException('Method must be a non-empty string.');
+ }
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/Response.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/Response.php
new file mode 100755
index 00000000..a3431363
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/Response.php
@@ -0,0 +1,78 @@
+ 'Continue', 101 => 'Switching Protocols', 102 => 'Processing', 200 => 'OK', 201 => 'Created', 202 => 'Accepted', 203 => 'Non-Authoritative Information', 204 => 'No Content', 205 => 'Reset Content', 206 => 'Partial Content', 207 => 'Multi-status', 208 => 'Already Reported', 300 => 'Multiple Choices', 301 => 'Moved Permanently', 302 => 'Found', 303 => 'See Other', 304 => 'Not Modified', 305 => 'Use Proxy', 306 => 'Switch Proxy', 307 => 'Temporary Redirect', 308 => 'Permanent Redirect', 400 => 'Bad Request', 401 => 'Unauthorized', 402 => 'Payment Required', 403 => 'Forbidden', 404 => 'Not Found', 405 => 'Method Not Allowed', 406 => 'Not Acceptable', 407 => 'Proxy Authentication Required', 408 => 'Request Time-out', 409 => 'Conflict', 410 => 'Gone', 411 => 'Length Required', 412 => 'Precondition Failed', 413 => 'Request Entity Too Large', 414 => 'Request-URI Too Large', 415 => 'Unsupported Media Type', 416 => 'Requested range not satisfiable', 417 => 'Expectation Failed', 418 => 'I\'m a teapot', 422 => 'Unprocessable Entity', 423 => 'Locked', 424 => 'Failed Dependency', 425 => 'Unordered Collection', 426 => 'Upgrade Required', 428 => 'Precondition Required', 429 => 'Too Many Requests', 431 => 'Request Header Fields Too Large', 451 => 'Unavailable For Legal Reasons', 500 => 'Internal Server Error', 501 => 'Not Implemented', 502 => 'Bad Gateway', 503 => 'Service Unavailable', 504 => 'Gateway Time-out', 505 => 'HTTP Version not supported', 506 => 'Variant Also Negotiates', 507 => 'Insufficient Storage', 508 => 'Loop Detected', 510 => 'Not Extended', 511 => 'Network Authentication Required'];
+ /** @var string */
+ private $reasonPhrase;
+ /** @var int */
+ private $statusCode;
+ /**
+ * @param int $status Status code
+ * @param (string|string[])[] $headers Response headers
+ * @param string|resource|StreamInterface|null $body Response body
+ * @param string $version Protocol version
+ * @param string|null $reason Reason phrase (when empty a default will be used based on the status code)
+ */
+ public function __construct(int $status = 200, array $headers = [], $body = null, string $version = '1.1', ?string $reason = null)
+ {
+ $this->assertStatusCodeRange($status);
+ $this->statusCode = $status;
+ if ($body !== '' && $body !== null) {
+ $this->stream = Utils::streamFor($body);
+ }
+ $this->setHeaders($headers);
+ if ($reason == '' && isset(self::PHRASES[$this->statusCode])) {
+ $this->reasonPhrase = self::PHRASES[$this->statusCode];
+ } else {
+ $this->reasonPhrase = (string) $reason;
+ }
+ $this->protocol = $version;
+ }
+ public function getStatusCode() : int
+ {
+ return $this->statusCode;
+ }
+ public function getReasonPhrase() : string
+ {
+ return $this->reasonPhrase;
+ }
+ public function withStatus($code, $reasonPhrase = '') : ResponseInterface
+ {
+ $this->assertStatusCodeIsInteger($code);
+ $code = (int) $code;
+ $this->assertStatusCodeRange($code);
+ $new = clone $this;
+ $new->statusCode = $code;
+ if ($reasonPhrase == '' && isset(self::PHRASES[$new->statusCode])) {
+ $reasonPhrase = self::PHRASES[$new->statusCode];
+ }
+ $new->reasonPhrase = (string) $reasonPhrase;
+ return $new;
+ }
+ /**
+ * @param mixed $statusCode
+ */
+ private function assertStatusCodeIsInteger($statusCode) : void
+ {
+ if (\filter_var($statusCode, \FILTER_VALIDATE_INT) === \false) {
+ throw new \InvalidArgumentException('Status code must be an integer value.');
+ }
+ }
+ private function assertStatusCodeRange(int $statusCode) : void
+ {
+ if ($statusCode < 100 || $statusCode >= 600) {
+ throw new \InvalidArgumentException('Status code must be an integer value between 1xx and 5xx.');
+ }
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/Rfc7230.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/Rfc7230.php
new file mode 100755
index 00000000..05ec303a
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/Rfc7230.php
@@ -0,0 +1,22 @@
+@,;:\\\"/[\\]?={}\x01- ]++):[ \t]*+((?:[ \t]*+[!-~\x80-\xff]++)*+)[ \t]*+\r?\n)m";
+ public const HEADER_FOLD_REGEX = "(\r?\n[ \t]++)";
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/ServerRequest.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/ServerRequest.php
new file mode 100755
index 00000000..30850604
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/ServerRequest.php
@@ -0,0 +1,266 @@
+serverParams = $serverParams;
+ parent::__construct($method, $uri, $headers, $body, $version);
+ }
+ /**
+ * Return an UploadedFile instance array.
+ *
+ * @param array $files An array which respect $_FILES structure
+ *
+ * @throws InvalidArgumentException for unrecognized values
+ */
+ public static function normalizeFiles(array $files) : array
+ {
+ $normalized = [];
+ foreach ($files as $key => $value) {
+ if ($value instanceof UploadedFileInterface) {
+ $normalized[$key] = $value;
+ } elseif (\is_array($value) && isset($value['tmp_name'])) {
+ $normalized[$key] = self::createUploadedFileFromSpec($value);
+ } elseif (\is_array($value)) {
+ $normalized[$key] = self::normalizeFiles($value);
+ continue;
+ } else {
+ throw new InvalidArgumentException('Invalid value in files specification');
+ }
+ }
+ return $normalized;
+ }
+ /**
+ * Create and return an UploadedFile instance from a $_FILES specification.
+ *
+ * If the specification represents an array of values, this method will
+ * delegate to normalizeNestedFileSpec() and return that return value.
+ *
+ * @param array $value $_FILES struct
+ *
+ * @return UploadedFileInterface|UploadedFileInterface[]
+ */
+ private static function createUploadedFileFromSpec(array $value)
+ {
+ if (\is_array($value['tmp_name'])) {
+ return self::normalizeNestedFileSpec($value);
+ }
+ return new UploadedFile($value['tmp_name'], (int) $value['size'], (int) $value['error'], $value['name'], $value['type']);
+ }
+ /**
+ * Normalize an array of file specifications.
+ *
+ * Loops through all nested files and returns a normalized array of
+ * UploadedFileInterface instances.
+ *
+ * @return UploadedFileInterface[]
+ */
+ private static function normalizeNestedFileSpec(array $files = []) : array
+ {
+ $normalizedFiles = [];
+ foreach (\array_keys($files['tmp_name']) as $key) {
+ $spec = ['tmp_name' => $files['tmp_name'][$key], 'size' => $files['size'][$key] ?? null, 'error' => $files['error'][$key] ?? null, 'name' => $files['name'][$key] ?? null, 'type' => $files['type'][$key] ?? null];
+ $normalizedFiles[$key] = self::createUploadedFileFromSpec($spec);
+ }
+ return $normalizedFiles;
+ }
+ /**
+ * Return a ServerRequest populated with superglobals:
+ * $_GET
+ * $_POST
+ * $_COOKIE
+ * $_FILES
+ * $_SERVER
+ */
+ public static function fromGlobals() : ServerRequestInterface
+ {
+ $method = $_SERVER['REQUEST_METHOD'] ?? 'GET';
+ $headers = \getallheaders();
+ $uri = self::getUriFromGlobals();
+ $body = new CachingStream(new LazyOpenStream('php://input', 'r+'));
+ $protocol = isset($_SERVER['SERVER_PROTOCOL']) ? \str_replace('HTTP/', '', $_SERVER['SERVER_PROTOCOL']) : '1.1';
+ $serverRequest = new ServerRequest($method, $uri, $headers, $body, $protocol, $_SERVER);
+ return $serverRequest->withCookieParams($_COOKIE)->withQueryParams($_GET)->withParsedBody($_POST)->withUploadedFiles(self::normalizeFiles($_FILES));
+ }
+ private static function extractHostAndPortFromAuthority(string $authority) : array
+ {
+ $uri = 'http://' . $authority;
+ $parts = \parse_url($uri);
+ if (\false === $parts) {
+ return [null, null];
+ }
+ $host = $parts['host'] ?? null;
+ $port = $parts['port'] ?? null;
+ return [$host, $port];
+ }
+ /**
+ * Get a Uri populated with values from $_SERVER.
+ */
+ public static function getUriFromGlobals() : UriInterface
+ {
+ $uri = new Uri('');
+ $uri = $uri->withScheme(!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' ? 'https' : 'http');
+ $hasPort = \false;
+ if (isset($_SERVER['HTTP_HOST'])) {
+ [$host, $port] = self::extractHostAndPortFromAuthority($_SERVER['HTTP_HOST']);
+ if ($host !== null) {
+ $uri = $uri->withHost($host);
+ }
+ if ($port !== null) {
+ $hasPort = \true;
+ $uri = $uri->withPort($port);
+ }
+ } elseif (isset($_SERVER['SERVER_NAME'])) {
+ $uri = $uri->withHost($_SERVER['SERVER_NAME']);
+ } elseif (isset($_SERVER['SERVER_ADDR'])) {
+ $uri = $uri->withHost($_SERVER['SERVER_ADDR']);
+ }
+ if (!$hasPort && isset($_SERVER['SERVER_PORT'])) {
+ $uri = $uri->withPort($_SERVER['SERVER_PORT']);
+ }
+ $hasQuery = \false;
+ if (isset($_SERVER['REQUEST_URI'])) {
+ $requestUriParts = \explode('?', $_SERVER['REQUEST_URI'], 2);
+ $uri = $uri->withPath($requestUriParts[0]);
+ if (isset($requestUriParts[1])) {
+ $hasQuery = \true;
+ $uri = $uri->withQuery($requestUriParts[1]);
+ }
+ }
+ if (!$hasQuery && isset($_SERVER['QUERY_STRING'])) {
+ $uri = $uri->withQuery($_SERVER['QUERY_STRING']);
+ }
+ return $uri;
+ }
+ public function getServerParams() : array
+ {
+ return $this->serverParams;
+ }
+ public function getUploadedFiles() : array
+ {
+ return $this->uploadedFiles;
+ }
+ public function withUploadedFiles(array $uploadedFiles) : ServerRequestInterface
+ {
+ $new = clone $this;
+ $new->uploadedFiles = $uploadedFiles;
+ return $new;
+ }
+ public function getCookieParams() : array
+ {
+ return $this->cookieParams;
+ }
+ public function withCookieParams(array $cookies) : ServerRequestInterface
+ {
+ $new = clone $this;
+ $new->cookieParams = $cookies;
+ return $new;
+ }
+ public function getQueryParams() : array
+ {
+ return $this->queryParams;
+ }
+ public function withQueryParams(array $query) : ServerRequestInterface
+ {
+ $new = clone $this;
+ $new->queryParams = $query;
+ return $new;
+ }
+ /**
+ * @return array|object|null
+ */
+ public function getParsedBody()
+ {
+ return $this->parsedBody;
+ }
+ public function withParsedBody($data) : ServerRequestInterface
+ {
+ $new = clone $this;
+ $new->parsedBody = $data;
+ return $new;
+ }
+ public function getAttributes() : array
+ {
+ return $this->attributes;
+ }
+ /**
+ * @return mixed
+ */
+ public function getAttribute($attribute, $default = null)
+ {
+ if (\false === \array_key_exists($attribute, $this->attributes)) {
+ return $default;
+ }
+ return $this->attributes[$attribute];
+ }
+ public function withAttribute($attribute, $value) : ServerRequestInterface
+ {
+ $new = clone $this;
+ $new->attributes[$attribute] = $value;
+ return $new;
+ }
+ public function withoutAttribute($attribute) : ServerRequestInterface
+ {
+ if (\false === \array_key_exists($attribute, $this->attributes)) {
+ return $this;
+ }
+ $new = clone $this;
+ unset($new->attributes[$attribute]);
+ return $new;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/Stream.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/Stream.php
new file mode 100755
index 00000000..50cc2db6
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/Stream.php
@@ -0,0 +1,235 @@
+size = $options['size'];
+ }
+ $this->customMetadata = $options['metadata'] ?? [];
+ $this->stream = $stream;
+ $meta = \stream_get_meta_data($this->stream);
+ $this->seekable = $meta['seekable'];
+ $this->readable = (bool) \preg_match(self::READABLE_MODES, $meta['mode']);
+ $this->writable = (bool) \preg_match(self::WRITABLE_MODES, $meta['mode']);
+ $this->uri = $this->getMetadata('uri');
+ }
+ /**
+ * Closes the stream when the destructed
+ */
+ public function __destruct()
+ {
+ $this->close();
+ }
+ public function __toString() : string
+ {
+ try {
+ if ($this->isSeekable()) {
+ $this->seek(0);
+ }
+ return $this->getContents();
+ } catch (\Throwable $e) {
+ if (\PHP_VERSION_ID >= 70400) {
+ throw $e;
+ }
+ \trigger_error(\sprintf('%s::__toString exception: %s', self::class, (string) $e), \E_USER_ERROR);
+ return '';
+ }
+ }
+ public function getContents() : string
+ {
+ if (!isset($this->stream)) {
+ throw new \RuntimeException('Stream is detached');
+ }
+ if (!$this->readable) {
+ throw new \RuntimeException('Cannot read from non-readable stream');
+ }
+ return Utils::tryGetContents($this->stream);
+ }
+ public function close() : void
+ {
+ if (isset($this->stream)) {
+ if (\is_resource($this->stream)) {
+ \fclose($this->stream);
+ }
+ $this->detach();
+ }
+ }
+ public function detach()
+ {
+ if (!isset($this->stream)) {
+ return null;
+ }
+ $result = $this->stream;
+ unset($this->stream);
+ $this->size = $this->uri = null;
+ $this->readable = $this->writable = $this->seekable = \false;
+ return $result;
+ }
+ public function getSize() : ?int
+ {
+ if ($this->size !== null) {
+ return $this->size;
+ }
+ if (!isset($this->stream)) {
+ return null;
+ }
+ // Clear the stat cache if the stream has a URI
+ if ($this->uri) {
+ \clearstatcache(\true, $this->uri);
+ }
+ $stats = \fstat($this->stream);
+ if (\is_array($stats) && isset($stats['size'])) {
+ $this->size = $stats['size'];
+ return $this->size;
+ }
+ return null;
+ }
+ public function isReadable() : bool
+ {
+ return $this->readable;
+ }
+ public function isWritable() : bool
+ {
+ return $this->writable;
+ }
+ public function isSeekable() : bool
+ {
+ return $this->seekable;
+ }
+ public function eof() : bool
+ {
+ if (!isset($this->stream)) {
+ throw new \RuntimeException('Stream is detached');
+ }
+ return \feof($this->stream);
+ }
+ public function tell() : int
+ {
+ if (!isset($this->stream)) {
+ throw new \RuntimeException('Stream is detached');
+ }
+ $result = \ftell($this->stream);
+ if ($result === \false) {
+ throw new \RuntimeException('Unable to determine stream position');
+ }
+ return $result;
+ }
+ public function rewind() : void
+ {
+ $this->seek(0);
+ }
+ public function seek($offset, $whence = \SEEK_SET) : void
+ {
+ $whence = (int) $whence;
+ if (!isset($this->stream)) {
+ throw new \RuntimeException('Stream is detached');
+ }
+ if (!$this->seekable) {
+ throw new \RuntimeException('Stream is not seekable');
+ }
+ if (\fseek($this->stream, $offset, $whence) === -1) {
+ throw new \RuntimeException('Unable to seek to stream position ' . $offset . ' with whence ' . \var_export($whence, \true));
+ }
+ }
+ public function read($length) : string
+ {
+ if (!isset($this->stream)) {
+ throw new \RuntimeException('Stream is detached');
+ }
+ if (!$this->readable) {
+ throw new \RuntimeException('Cannot read from non-readable stream');
+ }
+ if ($length < 0) {
+ throw new \RuntimeException('Length parameter cannot be negative');
+ }
+ if (0 === $length) {
+ return '';
+ }
+ try {
+ $string = \fread($this->stream, $length);
+ } catch (\Exception $e) {
+ throw new \RuntimeException('Unable to read from stream', 0, $e);
+ }
+ if (\false === $string) {
+ throw new \RuntimeException('Unable to read from stream');
+ }
+ return $string;
+ }
+ public function write($string) : int
+ {
+ if (!isset($this->stream)) {
+ throw new \RuntimeException('Stream is detached');
+ }
+ if (!$this->writable) {
+ throw new \RuntimeException('Cannot write to a non-writable stream');
+ }
+ // We can't know the size after writing anything
+ $this->size = null;
+ $result = \fwrite($this->stream, $string);
+ if ($result === \false) {
+ throw new \RuntimeException('Unable to write to stream');
+ }
+ return $result;
+ }
+ /**
+ * @return mixed
+ */
+ public function getMetadata($key = null)
+ {
+ if (!isset($this->stream)) {
+ return $key ? null : [];
+ } elseif (!$key) {
+ return $this->customMetadata + \stream_get_meta_data($this->stream);
+ } elseif (isset($this->customMetadata[$key])) {
+ return $this->customMetadata[$key];
+ }
+ $meta = \stream_get_meta_data($this->stream);
+ return $meta[$key] ?? null;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/StreamDecoratorTrait.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/StreamDecoratorTrait.php
new file mode 100755
index 00000000..309e44c2
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/StreamDecoratorTrait.php
@@ -0,0 +1,131 @@
+stream = $stream;
+ }
+ /**
+ * Magic method used to create a new stream if streams are not added in
+ * the constructor of a decorator (e.g., LazyOpenStream).
+ *
+ * @return StreamInterface
+ */
+ public function __get(string $name)
+ {
+ if ($name === 'stream') {
+ $this->stream = $this->createStream();
+ return $this->stream;
+ }
+ throw new \UnexpectedValueException("{$name} not found on class");
+ }
+ public function __toString() : string
+ {
+ try {
+ if ($this->isSeekable()) {
+ $this->seek(0);
+ }
+ return $this->getContents();
+ } catch (\Throwable $e) {
+ if (\PHP_VERSION_ID >= 70400) {
+ throw $e;
+ }
+ \trigger_error(\sprintf('%s::__toString exception: %s', self::class, (string) $e), \E_USER_ERROR);
+ return '';
+ }
+ }
+ public function getContents() : string
+ {
+ return Utils::copyToString($this);
+ }
+ /**
+ * Allow decorators to implement custom methods
+ *
+ * @return mixed
+ */
+ public function __call(string $method, array $args)
+ {
+ /** @var callable $callable */
+ $callable = [$this->stream, $method];
+ $result = $callable(...$args);
+ // Always return the wrapped object if the result is a return $this
+ return $result === $this->stream ? $this : $result;
+ }
+ public function close() : void
+ {
+ $this->stream->close();
+ }
+ /**
+ * @return mixed
+ */
+ public function getMetadata($key = null)
+ {
+ return $this->stream->getMetadata($key);
+ }
+ public function detach()
+ {
+ return $this->stream->detach();
+ }
+ public function getSize() : ?int
+ {
+ return $this->stream->getSize();
+ }
+ public function eof() : bool
+ {
+ return $this->stream->eof();
+ }
+ public function tell() : int
+ {
+ return $this->stream->tell();
+ }
+ public function isReadable() : bool
+ {
+ return $this->stream->isReadable();
+ }
+ public function isWritable() : bool
+ {
+ return $this->stream->isWritable();
+ }
+ public function isSeekable() : bool
+ {
+ return $this->stream->isSeekable();
+ }
+ public function rewind() : void
+ {
+ $this->seek(0);
+ }
+ public function seek($offset, $whence = \SEEK_SET) : void
+ {
+ $this->stream->seek($offset, $whence);
+ }
+ public function read($length) : string
+ {
+ return $this->stream->read($length);
+ }
+ public function write($string) : int
+ {
+ return $this->stream->write($string);
+ }
+ /**
+ * Implement in subclasses to dynamically create streams when requested.
+ *
+ * @throws \BadMethodCallException
+ */
+ protected function createStream() : StreamInterface
+ {
+ throw new \BadMethodCallException('Not implemented');
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/StreamWrapper.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/StreamWrapper.php
new file mode 100755
index 00000000..3b042c0a
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/StreamWrapper.php
@@ -0,0 +1,145 @@
+isReadable()) {
+ $mode = $stream->isWritable() ? 'r+' : 'r';
+ } elseif ($stream->isWritable()) {
+ $mode = 'w';
+ } else {
+ throw new \InvalidArgumentException('The stream must be readable, ' . 'writable, or both.');
+ }
+ return \fopen('guzzle://stream', $mode, \false, self::createStreamContext($stream));
+ }
+ /**
+ * Creates a stream context that can be used to open a stream as a php stream resource.
+ *
+ * @return resource
+ */
+ public static function createStreamContext(StreamInterface $stream)
+ {
+ return \stream_context_create(['guzzle' => ['stream' => $stream]]);
+ }
+ /**
+ * Registers the stream wrapper if needed
+ */
+ public static function register() : void
+ {
+ if (!\in_array('guzzle', \stream_get_wrappers())) {
+ \stream_wrapper_register('guzzle', __CLASS__);
+ }
+ }
+ public function stream_open(string $path, string $mode, int $options, ?string &$opened_path = null) : bool
+ {
+ $options = \stream_context_get_options($this->context);
+ if (!isset($options['guzzle']['stream'])) {
+ return \false;
+ }
+ $this->mode = $mode;
+ $this->stream = $options['guzzle']['stream'];
+ return \true;
+ }
+ public function stream_read(int $count) : string
+ {
+ return $this->stream->read($count);
+ }
+ public function stream_write(string $data) : int
+ {
+ return $this->stream->write($data);
+ }
+ public function stream_tell() : int
+ {
+ return $this->stream->tell();
+ }
+ public function stream_eof() : bool
+ {
+ return $this->stream->eof();
+ }
+ public function stream_seek(int $offset, int $whence) : bool
+ {
+ $this->stream->seek($offset, $whence);
+ return \true;
+ }
+ /**
+ * @return resource|false
+ */
+ public function stream_cast(int $cast_as)
+ {
+ $stream = clone $this->stream;
+ $resource = $stream->detach();
+ return $resource ?? \false;
+ }
+ /**
+ * @return array{
+ * dev: int,
+ * ino: int,
+ * mode: int,
+ * nlink: int,
+ * uid: int,
+ * gid: int,
+ * rdev: int,
+ * size: int,
+ * atime: int,
+ * mtime: int,
+ * ctime: int,
+ * blksize: int,
+ * blocks: int
+ * }|false
+ */
+ public function stream_stat()
+ {
+ if ($this->stream->getSize() === null) {
+ return \false;
+ }
+ static $modeMap = ['r' => 33060, 'rb' => 33060, 'r+' => 33206, 'w' => 33188, 'wb' => 33188];
+ return ['dev' => 0, 'ino' => 0, 'mode' => $modeMap[$this->mode], 'nlink' => 0, 'uid' => 0, 'gid' => 0, 'rdev' => 0, 'size' => $this->stream->getSize() ?: 0, 'atime' => 0, 'mtime' => 0, 'ctime' => 0, 'blksize' => 0, 'blocks' => 0];
+ }
+ /**
+ * @return array{
+ * dev: int,
+ * ino: int,
+ * mode: int,
+ * nlink: int,
+ * uid: int,
+ * gid: int,
+ * rdev: int,
+ * size: int,
+ * atime: int,
+ * mtime: int,
+ * ctime: int,
+ * blksize: int,
+ * blocks: int
+ * }
+ */
+ public function url_stat(string $path, int $flags) : array
+ {
+ return ['dev' => 0, 'ino' => 0, 'mode' => 0, 'nlink' => 0, 'uid' => 0, 'gid' => 0, 'rdev' => 0, 'size' => 0, 'atime' => 0, 'mtime' => 0, 'ctime' => 0, 'blksize' => 0, 'blocks' => 0];
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/UploadedFile.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/UploadedFile.php
new file mode 100755
index 00000000..069ea20e
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/UploadedFile.php
@@ -0,0 +1,152 @@
+ 'UPLOAD_ERR_OK', \UPLOAD_ERR_INI_SIZE => 'UPLOAD_ERR_INI_SIZE', \UPLOAD_ERR_FORM_SIZE => 'UPLOAD_ERR_FORM_SIZE', \UPLOAD_ERR_PARTIAL => 'UPLOAD_ERR_PARTIAL', \UPLOAD_ERR_NO_FILE => 'UPLOAD_ERR_NO_FILE', \UPLOAD_ERR_NO_TMP_DIR => 'UPLOAD_ERR_NO_TMP_DIR', \UPLOAD_ERR_CANT_WRITE => 'UPLOAD_ERR_CANT_WRITE', \UPLOAD_ERR_EXTENSION => 'UPLOAD_ERR_EXTENSION'];
+ /**
+ * @var string|null
+ */
+ private $clientFilename;
+ /**
+ * @var string|null
+ */
+ private $clientMediaType;
+ /**
+ * @var int
+ */
+ private $error;
+ /**
+ * @var string|null
+ */
+ private $file;
+ /**
+ * @var bool
+ */
+ private $moved = \false;
+ /**
+ * @var int|null
+ */
+ private $size;
+ /**
+ * @var StreamInterface|null
+ */
+ private $stream;
+ /**
+ * @param StreamInterface|string|resource $streamOrFile
+ */
+ public function __construct($streamOrFile, ?int $size, int $errorStatus, ?string $clientFilename = null, ?string $clientMediaType = null)
+ {
+ $this->setError($errorStatus);
+ $this->size = $size;
+ $this->clientFilename = $clientFilename;
+ $this->clientMediaType = $clientMediaType;
+ if ($this->isOk()) {
+ $this->setStreamOrFile($streamOrFile);
+ }
+ }
+ /**
+ * Depending on the value set file or stream variable
+ *
+ * @param StreamInterface|string|resource $streamOrFile
+ *
+ * @throws InvalidArgumentException
+ */
+ private function setStreamOrFile($streamOrFile) : void
+ {
+ if (\is_string($streamOrFile)) {
+ $this->file = $streamOrFile;
+ } elseif (\is_resource($streamOrFile)) {
+ $this->stream = new Stream($streamOrFile);
+ } elseif ($streamOrFile instanceof StreamInterface) {
+ $this->stream = $streamOrFile;
+ } else {
+ throw new InvalidArgumentException('Invalid stream or file provided for UploadedFile');
+ }
+ }
+ /**
+ * @throws InvalidArgumentException
+ */
+ private function setError(int $error) : void
+ {
+ if (!isset(UploadedFile::ERROR_MAP[$error])) {
+ throw new InvalidArgumentException('Invalid error status for UploadedFile');
+ }
+ $this->error = $error;
+ }
+ private static function isStringNotEmpty($param) : bool
+ {
+ return \is_string($param) && \false === empty($param);
+ }
+ /**
+ * Return true if there is no upload error
+ */
+ private function isOk() : bool
+ {
+ return $this->error === \UPLOAD_ERR_OK;
+ }
+ public function isMoved() : bool
+ {
+ return $this->moved;
+ }
+ /**
+ * @throws RuntimeException if is moved or not ok
+ */
+ private function validateActive() : void
+ {
+ if (\false === $this->isOk()) {
+ throw new RuntimeException(\sprintf('Cannot retrieve stream due to upload error (%s)', self::ERROR_MAP[$this->error]));
+ }
+ if ($this->isMoved()) {
+ throw new RuntimeException('Cannot retrieve stream after it has already been moved');
+ }
+ }
+ public function getStream() : StreamInterface
+ {
+ $this->validateActive();
+ if ($this->stream instanceof StreamInterface) {
+ return $this->stream;
+ }
+ /** @var string $file */
+ $file = $this->file;
+ return new LazyOpenStream($file, 'r+');
+ }
+ public function moveTo($targetPath) : void
+ {
+ $this->validateActive();
+ if (\false === self::isStringNotEmpty($targetPath)) {
+ throw new InvalidArgumentException('Invalid path provided for move operation; must be a non-empty string');
+ }
+ if ($this->file) {
+ $this->moved = \PHP_SAPI === 'cli' ? \rename($this->file, $targetPath) : \move_uploaded_file($this->file, $targetPath);
+ } else {
+ Utils::copyToStream($this->getStream(), new LazyOpenStream($targetPath, 'w'));
+ $this->moved = \true;
+ }
+ if (\false === $this->moved) {
+ throw new RuntimeException(\sprintf('Uploaded file could not be moved to %s', $targetPath));
+ }
+ }
+ public function getSize() : ?int
+ {
+ return $this->size;
+ }
+ public function getError() : int
+ {
+ return $this->error;
+ }
+ public function getClientFilename() : ?string
+ {
+ return $this->clientFilename;
+ }
+ public function getClientMediaType() : ?string
+ {
+ return $this->clientMediaType;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/Uri.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/Uri.php
new file mode 100755
index 00000000..ae0343b6
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/Uri.php
@@ -0,0 +1,572 @@
+ 80, 'https' => 443, 'ftp' => 21, 'gopher' => 70, 'nntp' => 119, 'news' => 119, 'telnet' => 23, 'tn3270' => 23, 'imap' => 143, 'pop' => 110, 'ldap' => 389];
+ /**
+ * Unreserved characters for use in a regex.
+ *
+ * @see https://datatracker.ietf.org/doc/html/rfc3986#section-2.3
+ */
+ private const CHAR_UNRESERVED = 'a-zA-Z0-9_\\-\\.~';
+ /**
+ * Sub-delims for use in a regex.
+ *
+ * @see https://datatracker.ietf.org/doc/html/rfc3986#section-2.2
+ */
+ private const CHAR_SUB_DELIMS = '!\\$&\'\\(\\)\\*\\+,;=';
+ private const QUERY_SEPARATORS_REPLACEMENT = ['=' => '%3D', '&' => '%26'];
+ /** @var string Uri scheme. */
+ private $scheme = '';
+ /** @var string Uri user info. */
+ private $userInfo = '';
+ /** @var string Uri host. */
+ private $host = '';
+ /** @var int|null Uri port. */
+ private $port;
+ /** @var string Uri path. */
+ private $path = '';
+ /** @var string Uri query string. */
+ private $query = '';
+ /** @var string Uri fragment. */
+ private $fragment = '';
+ /** @var string|null String representation */
+ private $composedComponents;
+ public function __construct(string $uri = '')
+ {
+ if ($uri !== '') {
+ $parts = self::parse($uri);
+ if ($parts === \false) {
+ throw new MalformedUriException("Unable to parse URI: {$uri}");
+ }
+ $this->applyParts($parts);
+ }
+ }
+ /**
+ * UTF-8 aware \parse_url() replacement.
+ *
+ * The internal function produces broken output for non ASCII domain names
+ * (IDN) when used with locales other than "C".
+ *
+ * On the other hand, cURL understands IDN correctly only when UTF-8 locale
+ * is configured ("C.UTF-8", "en_US.UTF-8", etc.).
+ *
+ * @see https://bugs.php.net/bug.php?id=52923
+ * @see https://www.php.net/manual/en/function.parse-url.php#114817
+ * @see https://curl.haxx.se/libcurl/c/CURLOPT_URL.html#ENCODING
+ *
+ * @return array|false
+ */
+ private static function parse(string $url)
+ {
+ // If IPv6
+ $prefix = '';
+ if (\preg_match('%^(.*://\\[[0-9:a-fA-F]+\\])(.*?)$%', $url, $matches)) {
+ /** @var array{0:string, 1:string, 2:string} $matches */
+ $prefix = $matches[1];
+ $url = $matches[2];
+ }
+ /** @var string */
+ $encodedUrl = \preg_replace_callback('%[^:/@?&=#]+%usD', static function ($matches) {
+ return \urlencode($matches[0]);
+ }, $url);
+ $result = \parse_url($prefix . $encodedUrl);
+ if ($result === \false) {
+ return \false;
+ }
+ return \array_map('urldecode', $result);
+ }
+ public function __toString() : string
+ {
+ if ($this->composedComponents === null) {
+ $this->composedComponents = self::composeComponents($this->scheme, $this->getAuthority(), $this->path, $this->query, $this->fragment);
+ }
+ return $this->composedComponents;
+ }
+ /**
+ * Composes a URI reference string from its various components.
+ *
+ * Usually this method does not need to be called manually but instead is used indirectly via
+ * `Psr\Http\Message\UriInterface::__toString`.
+ *
+ * PSR-7 UriInterface treats an empty component the same as a missing component as
+ * getQuery(), getFragment() etc. always return a string. This explains the slight
+ * difference to RFC 3986 Section 5.3.
+ *
+ * Another adjustment is that the authority separator is added even when the authority is missing/empty
+ * for the "file" scheme. This is because PHP stream functions like `file_get_contents` only work with
+ * `file:///myfile` but not with `file:/myfile` although they are equivalent according to RFC 3986. But
+ * `file:///` is the more common syntax for the file scheme anyway (Chrome for example redirects to
+ * that format).
+ *
+ * @see https://datatracker.ietf.org/doc/html/rfc3986#section-5.3
+ */
+ public static function composeComponents(?string $scheme, ?string $authority, string $path, ?string $query, ?string $fragment) : string
+ {
+ $uri = '';
+ // weak type checks to also accept null until we can add scalar type hints
+ if ($scheme != '') {
+ $uri .= $scheme . ':';
+ }
+ if ($authority != '' || $scheme === 'file') {
+ $uri .= '//' . $authority;
+ }
+ if ($authority != '' && $path != '' && $path[0] != '/') {
+ $path = '/' . $path;
+ }
+ $uri .= $path;
+ if ($query != '') {
+ $uri .= '?' . $query;
+ }
+ if ($fragment != '') {
+ $uri .= '#' . $fragment;
+ }
+ return $uri;
+ }
+ /**
+ * Whether the URI has the default port of the current scheme.
+ *
+ * `Psr\Http\Message\UriInterface::getPort` may return null or the standard port. This method can be used
+ * independently of the implementation.
+ */
+ public static function isDefaultPort(UriInterface $uri) : bool
+ {
+ return $uri->getPort() === null || isset(self::DEFAULT_PORTS[$uri->getScheme()]) && $uri->getPort() === self::DEFAULT_PORTS[$uri->getScheme()];
+ }
+ /**
+ * Whether the URI is absolute, i.e. it has a scheme.
+ *
+ * An instance of UriInterface can either be an absolute URI or a relative reference. This method returns true
+ * if it is the former. An absolute URI has a scheme. A relative reference is used to express a URI relative
+ * to another URI, the base URI. Relative references can be divided into several forms:
+ * - network-path references, e.g. '//example.com/path'
+ * - absolute-path references, e.g. '/path'
+ * - relative-path references, e.g. 'subpath'
+ *
+ * @see Uri::isNetworkPathReference
+ * @see Uri::isAbsolutePathReference
+ * @see Uri::isRelativePathReference
+ * @see https://datatracker.ietf.org/doc/html/rfc3986#section-4
+ */
+ public static function isAbsolute(UriInterface $uri) : bool
+ {
+ return $uri->getScheme() !== '';
+ }
+ /**
+ * Whether the URI is a network-path reference.
+ *
+ * A relative reference that begins with two slash characters is termed an network-path reference.
+ *
+ * @see https://datatracker.ietf.org/doc/html/rfc3986#section-4.2
+ */
+ public static function isNetworkPathReference(UriInterface $uri) : bool
+ {
+ return $uri->getScheme() === '' && $uri->getAuthority() !== '';
+ }
+ /**
+ * Whether the URI is a absolute-path reference.
+ *
+ * A relative reference that begins with a single slash character is termed an absolute-path reference.
+ *
+ * @see https://datatracker.ietf.org/doc/html/rfc3986#section-4.2
+ */
+ public static function isAbsolutePathReference(UriInterface $uri) : bool
+ {
+ return $uri->getScheme() === '' && $uri->getAuthority() === '' && isset($uri->getPath()[0]) && $uri->getPath()[0] === '/';
+ }
+ /**
+ * Whether the URI is a relative-path reference.
+ *
+ * A relative reference that does not begin with a slash character is termed a relative-path reference.
+ *
+ * @see https://datatracker.ietf.org/doc/html/rfc3986#section-4.2
+ */
+ public static function isRelativePathReference(UriInterface $uri) : bool
+ {
+ return $uri->getScheme() === '' && $uri->getAuthority() === '' && (!isset($uri->getPath()[0]) || $uri->getPath()[0] !== '/');
+ }
+ /**
+ * Whether the URI is a same-document reference.
+ *
+ * A same-document reference refers to a URI that is, aside from its fragment
+ * component, identical to the base URI. When no base URI is given, only an empty
+ * URI reference (apart from its fragment) is considered a same-document reference.
+ *
+ * @param UriInterface $uri The URI to check
+ * @param UriInterface|null $base An optional base URI to compare against
+ *
+ * @see https://datatracker.ietf.org/doc/html/rfc3986#section-4.4
+ */
+ public static function isSameDocumentReference(UriInterface $uri, ?UriInterface $base = null) : bool
+ {
+ if ($base !== null) {
+ $uri = UriResolver::resolve($base, $uri);
+ return $uri->getScheme() === $base->getScheme() && $uri->getAuthority() === $base->getAuthority() && $uri->getPath() === $base->getPath() && $uri->getQuery() === $base->getQuery();
+ }
+ return $uri->getScheme() === '' && $uri->getAuthority() === '' && $uri->getPath() === '' && $uri->getQuery() === '';
+ }
+ /**
+ * Creates a new URI with a specific query string value removed.
+ *
+ * Any existing query string values that exactly match the provided key are
+ * removed.
+ *
+ * @param UriInterface $uri URI to use as a base.
+ * @param string $key Query string key to remove.
+ */
+ public static function withoutQueryValue(UriInterface $uri, string $key) : UriInterface
+ {
+ $result = self::getFilteredQueryString($uri, [$key]);
+ return $uri->withQuery(\implode('&', $result));
+ }
+ /**
+ * Creates a new URI with a specific query string value.
+ *
+ * Any existing query string values that exactly match the provided key are
+ * removed and replaced with the given key value pair.
+ *
+ * A value of null will set the query string key without a value, e.g. "key"
+ * instead of "key=value".
+ *
+ * @param UriInterface $uri URI to use as a base.
+ * @param string $key Key to set.
+ * @param string|null $value Value to set
+ */
+ public static function withQueryValue(UriInterface $uri, string $key, ?string $value) : UriInterface
+ {
+ $result = self::getFilteredQueryString($uri, [$key]);
+ $result[] = self::generateQueryString($key, $value);
+ return $uri->withQuery(\implode('&', $result));
+ }
+ /**
+ * Creates a new URI with multiple specific query string values.
+ *
+ * It has the same behavior as withQueryValue() but for an associative array of key => value.
+ *
+ * @param UriInterface $uri URI to use as a base.
+ * @param (string|null)[] $keyValueArray Associative array of key and values
+ */
+ public static function withQueryValues(UriInterface $uri, array $keyValueArray) : UriInterface
+ {
+ $result = self::getFilteredQueryString($uri, \array_keys($keyValueArray));
+ foreach ($keyValueArray as $key => $value) {
+ $result[] = self::generateQueryString((string) $key, $value !== null ? (string) $value : null);
+ }
+ return $uri->withQuery(\implode('&', $result));
+ }
+ /**
+ * Creates a URI from a hash of `parse_url` components.
+ *
+ * @see https://www.php.net/manual/en/function.parse-url.php
+ *
+ * @throws MalformedUriException If the components do not form a valid URI.
+ */
+ public static function fromParts(array $parts) : UriInterface
+ {
+ $uri = new self();
+ $uri->applyParts($parts);
+ $uri->validateState();
+ return $uri;
+ }
+ public function getScheme() : string
+ {
+ return $this->scheme;
+ }
+ public function getAuthority() : string
+ {
+ $authority = $this->host;
+ if ($this->userInfo !== '') {
+ $authority = $this->userInfo . '@' . $authority;
+ }
+ if ($this->port !== null) {
+ $authority .= ':' . $this->port;
+ }
+ return $authority;
+ }
+ public function getUserInfo() : string
+ {
+ return $this->userInfo;
+ }
+ public function getHost() : string
+ {
+ return $this->host;
+ }
+ public function getPort() : ?int
+ {
+ return $this->port;
+ }
+ public function getPath() : string
+ {
+ return $this->path;
+ }
+ public function getQuery() : string
+ {
+ return $this->query;
+ }
+ public function getFragment() : string
+ {
+ return $this->fragment;
+ }
+ public function withScheme($scheme) : UriInterface
+ {
+ $scheme = $this->filterScheme($scheme);
+ if ($this->scheme === $scheme) {
+ return $this;
+ }
+ $new = clone $this;
+ $new->scheme = $scheme;
+ $new->composedComponents = null;
+ $new->removeDefaultPort();
+ $new->validateState();
+ return $new;
+ }
+ public function withUserInfo($user, $password = null) : UriInterface
+ {
+ $info = $this->filterUserInfoComponent($user);
+ if ($password !== null) {
+ $info .= ':' . $this->filterUserInfoComponent($password);
+ }
+ if ($this->userInfo === $info) {
+ return $this;
+ }
+ $new = clone $this;
+ $new->userInfo = $info;
+ $new->composedComponents = null;
+ $new->validateState();
+ return $new;
+ }
+ public function withHost($host) : UriInterface
+ {
+ $host = $this->filterHost($host);
+ if ($this->host === $host) {
+ return $this;
+ }
+ $new = clone $this;
+ $new->host = $host;
+ $new->composedComponents = null;
+ $new->validateState();
+ return $new;
+ }
+ public function withPort($port) : UriInterface
+ {
+ $port = $this->filterPort($port);
+ if ($this->port === $port) {
+ return $this;
+ }
+ $new = clone $this;
+ $new->port = $port;
+ $new->composedComponents = null;
+ $new->removeDefaultPort();
+ $new->validateState();
+ return $new;
+ }
+ public function withPath($path) : UriInterface
+ {
+ $path = $this->filterPath($path);
+ if ($this->path === $path) {
+ return $this;
+ }
+ $new = clone $this;
+ $new->path = $path;
+ $new->composedComponents = null;
+ $new->validateState();
+ return $new;
+ }
+ public function withQuery($query) : UriInterface
+ {
+ $query = $this->filterQueryAndFragment($query);
+ if ($this->query === $query) {
+ return $this;
+ }
+ $new = clone $this;
+ $new->query = $query;
+ $new->composedComponents = null;
+ return $new;
+ }
+ public function withFragment($fragment) : UriInterface
+ {
+ $fragment = $this->filterQueryAndFragment($fragment);
+ if ($this->fragment === $fragment) {
+ return $this;
+ }
+ $new = clone $this;
+ $new->fragment = $fragment;
+ $new->composedComponents = null;
+ return $new;
+ }
+ public function jsonSerialize() : string
+ {
+ return $this->__toString();
+ }
+ /**
+ * Apply parse_url parts to a URI.
+ *
+ * @param array $parts Array of parse_url parts to apply.
+ */
+ private function applyParts(array $parts) : void
+ {
+ $this->scheme = isset($parts['scheme']) ? $this->filterScheme($parts['scheme']) : '';
+ $this->userInfo = isset($parts['user']) ? $this->filterUserInfoComponent($parts['user']) : '';
+ $this->host = isset($parts['host']) ? $this->filterHost($parts['host']) : '';
+ $this->port = isset($parts['port']) ? $this->filterPort($parts['port']) : null;
+ $this->path = isset($parts['path']) ? $this->filterPath($parts['path']) : '';
+ $this->query = isset($parts['query']) ? $this->filterQueryAndFragment($parts['query']) : '';
+ $this->fragment = isset($parts['fragment']) ? $this->filterQueryAndFragment($parts['fragment']) : '';
+ if (isset($parts['pass'])) {
+ $this->userInfo .= ':' . $this->filterUserInfoComponent($parts['pass']);
+ }
+ $this->removeDefaultPort();
+ }
+ /**
+ * @param mixed $scheme
+ *
+ * @throws \InvalidArgumentException If the scheme is invalid.
+ */
+ private function filterScheme($scheme) : string
+ {
+ if (!\is_string($scheme)) {
+ throw new \InvalidArgumentException('Scheme must be a string');
+ }
+ return \strtr($scheme, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz');
+ }
+ /**
+ * @param mixed $component
+ *
+ * @throws \InvalidArgumentException If the user info is invalid.
+ */
+ private function filterUserInfoComponent($component) : string
+ {
+ if (!\is_string($component)) {
+ throw new \InvalidArgumentException('User info must be a string');
+ }
+ return \preg_replace_callback('/(?:[^%' . self::CHAR_UNRESERVED . self::CHAR_SUB_DELIMS . ']+|%(?![A-Fa-f0-9]{2}))/', [$this, 'rawurlencodeMatchZero'], $component);
+ }
+ /**
+ * @param mixed $host
+ *
+ * @throws \InvalidArgumentException If the host is invalid.
+ */
+ private function filterHost($host) : string
+ {
+ if (!\is_string($host)) {
+ throw new \InvalidArgumentException('Host must be a string');
+ }
+ return \strtr($host, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz');
+ }
+ /**
+ * @param mixed $port
+ *
+ * @throws \InvalidArgumentException If the port is invalid.
+ */
+ private function filterPort($port) : ?int
+ {
+ if ($port === null) {
+ return null;
+ }
+ $port = (int) $port;
+ if (0 > $port || 0xffff < $port) {
+ throw new \InvalidArgumentException(\sprintf('Invalid port: %d. Must be between 0 and 65535', $port));
+ }
+ return $port;
+ }
+ /**
+ * @param (string|int)[] $keys
+ *
+ * @return string[]
+ */
+ private static function getFilteredQueryString(UriInterface $uri, array $keys) : array
+ {
+ $current = $uri->getQuery();
+ if ($current === '') {
+ return [];
+ }
+ $decodedKeys = \array_map(function ($k) : string {
+ return \rawurldecode((string) $k);
+ }, $keys);
+ return \array_filter(\explode('&', $current), function ($part) use($decodedKeys) {
+ return !\in_array(\rawurldecode(\explode('=', $part)[0]), $decodedKeys, \true);
+ });
+ }
+ private static function generateQueryString(string $key, ?string $value) : string
+ {
+ // Query string separators ("=", "&") within the key or value need to be encoded
+ // (while preventing double-encoding) before setting the query string. All other
+ // chars that need percent-encoding will be encoded by withQuery().
+ $queryString = \strtr($key, self::QUERY_SEPARATORS_REPLACEMENT);
+ if ($value !== null) {
+ $queryString .= '=' . \strtr($value, self::QUERY_SEPARATORS_REPLACEMENT);
+ }
+ return $queryString;
+ }
+ private function removeDefaultPort() : void
+ {
+ if ($this->port !== null && self::isDefaultPort($this)) {
+ $this->port = null;
+ }
+ }
+ /**
+ * Filters the path of a URI
+ *
+ * @param mixed $path
+ *
+ * @throws \InvalidArgumentException If the path is invalid.
+ */
+ private function filterPath($path) : string
+ {
+ if (!\is_string($path)) {
+ throw new \InvalidArgumentException('Path must be a string');
+ }
+ return \preg_replace_callback('/(?:[^' . self::CHAR_UNRESERVED . self::CHAR_SUB_DELIMS . '%:@\\/]++|%(?![A-Fa-f0-9]{2}))/', [$this, 'rawurlencodeMatchZero'], $path);
+ }
+ /**
+ * Filters the query string or fragment of a URI.
+ *
+ * @param mixed $str
+ *
+ * @throws \InvalidArgumentException If the query or fragment is invalid.
+ */
+ private function filterQueryAndFragment($str) : string
+ {
+ if (!\is_string($str)) {
+ throw new \InvalidArgumentException('Query and fragment must be a string');
+ }
+ return \preg_replace_callback('/(?:[^' . self::CHAR_UNRESERVED . self::CHAR_SUB_DELIMS . '%:@\\/\\?]++|%(?![A-Fa-f0-9]{2}))/', [$this, 'rawurlencodeMatchZero'], $str);
+ }
+ private function rawurlencodeMatchZero(array $match) : string
+ {
+ return \rawurlencode($match[0]);
+ }
+ private function validateState() : void
+ {
+ if ($this->host === '' && ($this->scheme === 'http' || $this->scheme === 'https')) {
+ $this->host = self::HTTP_DEFAULT_HOST;
+ }
+ if ($this->getAuthority() === '') {
+ if (0 === \strpos($this->path, '//')) {
+ throw new MalformedUriException('The path of a URI without an authority must not start with two slashes "//"');
+ }
+ if ($this->scheme === '' && \false !== \strpos(\explode('/', $this->path, 2)[0], ':')) {
+ throw new MalformedUriException('A relative URI must not have a path beginning with a segment containing a colon');
+ }
+ }
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/UriComparator.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/UriComparator.php
new file mode 100755
index 00000000..b2af8899
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/UriComparator.php
@@ -0,0 +1,43 @@
+getHost(), $modified->getHost()) !== 0) {
+ return \true;
+ }
+ if ($original->getScheme() !== $modified->getScheme()) {
+ return \true;
+ }
+ if (self::computePort($original) !== self::computePort($modified)) {
+ return \true;
+ }
+ return \false;
+ }
+ private static function computePort(UriInterface $uri) : int
+ {
+ $port = $uri->getPort();
+ if (null !== $port) {
+ return $port;
+ }
+ return 'https' === $uri->getScheme() ? 443 : 80;
+ }
+ private function __construct()
+ {
+ // cannot be instantiated
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/UriNormalizer.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/UriNormalizer.php
new file mode 100755
index 00000000..ed4e89ea
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/UriNormalizer.php
@@ -0,0 +1,175 @@
+getPath() === '' && ($uri->getScheme() === 'http' || $uri->getScheme() === 'https')) {
+ $uri = $uri->withPath('/');
+ }
+ if ($flags & self::REMOVE_DEFAULT_HOST && $uri->getScheme() === 'file' && $uri->getHost() === 'localhost') {
+ $uri = $uri->withHost('');
+ }
+ if ($flags & self::REMOVE_DEFAULT_PORT && $uri->getPort() !== null && Uri::isDefaultPort($uri)) {
+ $uri = $uri->withPort(null);
+ }
+ if ($flags & self::REMOVE_DOT_SEGMENTS && !Uri::isRelativePathReference($uri)) {
+ $uri = $uri->withPath(UriResolver::removeDotSegments($uri->getPath()));
+ }
+ if ($flags & self::REMOVE_DUPLICATE_SLASHES) {
+ $uri = $uri->withPath(\preg_replace('#//++#', '/', $uri->getPath()));
+ }
+ if ($flags & self::SORT_QUERY_PARAMETERS && $uri->getQuery() !== '') {
+ $queryKeyValues = \explode('&', $uri->getQuery());
+ \sort($queryKeyValues);
+ $uri = $uri->withQuery(\implode('&', $queryKeyValues));
+ }
+ return $uri;
+ }
+ /**
+ * Whether two URIs can be considered equivalent.
+ *
+ * Both URIs are normalized automatically before comparison with the given $normalizations bitmask. The method also
+ * accepts relative URI references and returns true when they are equivalent. This of course assumes they will be
+ * resolved against the same base URI. If this is not the case, determination of equivalence or difference of
+ * relative references does not mean anything.
+ *
+ * @param UriInterface $uri1 An URI to compare
+ * @param UriInterface $uri2 An URI to compare
+ * @param int $normalizations A bitmask of normalizations to apply, see constants
+ *
+ * @see https://datatracker.ietf.org/doc/html/rfc3986#section-6.1
+ */
+ public static function isEquivalent(UriInterface $uri1, UriInterface $uri2, int $normalizations = self::PRESERVING_NORMALIZATIONS) : bool
+ {
+ return (string) self::normalize($uri1, $normalizations) === (string) self::normalize($uri2, $normalizations);
+ }
+ private static function capitalizePercentEncoding(UriInterface $uri) : UriInterface
+ {
+ $regex = '/(?:%[A-Fa-f0-9]{2})++/';
+ $callback = function (array $match) : string {
+ return \strtoupper($match[0]);
+ };
+ return $uri->withPath(\preg_replace_callback($regex, $callback, $uri->getPath()))->withQuery(\preg_replace_callback($regex, $callback, $uri->getQuery()));
+ }
+ private static function decodeUnreservedCharacters(UriInterface $uri) : UriInterface
+ {
+ $regex = '/%(?:2D|2E|5F|7E|3[0-9]|[46][1-9A-F]|[57][0-9A])/i';
+ $callback = function (array $match) : string {
+ return \rawurldecode($match[0]);
+ };
+ return $uri->withPath(\preg_replace_callback($regex, $callback, $uri->getPath()))->withQuery(\preg_replace_callback($regex, $callback, $uri->getQuery()));
+ }
+ private function __construct()
+ {
+ // cannot be instantiated
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/UriResolver.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/UriResolver.php
new file mode 100755
index 00000000..37a1cc16
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/UriResolver.php
@@ -0,0 +1,180 @@
+getScheme() != '') {
+ return $rel->withPath(self::removeDotSegments($rel->getPath()));
+ }
+ if ($rel->getAuthority() != '') {
+ $targetAuthority = $rel->getAuthority();
+ $targetPath = self::removeDotSegments($rel->getPath());
+ $targetQuery = $rel->getQuery();
+ } else {
+ $targetAuthority = $base->getAuthority();
+ if ($rel->getPath() === '') {
+ $targetPath = $base->getPath();
+ $targetQuery = $rel->getQuery() != '' ? $rel->getQuery() : $base->getQuery();
+ } else {
+ if ($rel->getPath()[0] === '/') {
+ $targetPath = $rel->getPath();
+ } else {
+ if ($targetAuthority != '' && $base->getPath() === '') {
+ $targetPath = '/' . $rel->getPath();
+ } else {
+ $lastSlashPos = \strrpos($base->getPath(), '/');
+ if ($lastSlashPos === \false) {
+ $targetPath = $rel->getPath();
+ } else {
+ $targetPath = \substr($base->getPath(), 0, $lastSlashPos + 1) . $rel->getPath();
+ }
+ }
+ }
+ $targetPath = self::removeDotSegments($targetPath);
+ $targetQuery = $rel->getQuery();
+ }
+ }
+ return new Uri(Uri::composeComponents($base->getScheme(), $targetAuthority, $targetPath, $targetQuery, $rel->getFragment()));
+ }
+ /**
+ * Returns the target URI as a relative reference from the base URI.
+ *
+ * This method is the counterpart to resolve():
+ *
+ * (string) $target === (string) UriResolver::resolve($base, UriResolver::relativize($base, $target))
+ *
+ * One use-case is to use the current request URI as base URI and then generate relative links in your documents
+ * to reduce the document size or offer self-contained downloadable document archives.
+ *
+ * $base = new Uri('http://example.com/a/b/');
+ * echo UriResolver::relativize($base, new Uri('http://example.com/a/b/c')); // prints 'c'.
+ * echo UriResolver::relativize($base, new Uri('http://example.com/a/x/y')); // prints '../x/y'.
+ * echo UriResolver::relativize($base, new Uri('http://example.com/a/b/?q')); // prints '?q'.
+ * echo UriResolver::relativize($base, new Uri('http://example.org/a/b/')); // prints '//example.org/a/b/'.
+ *
+ * This method also accepts a target that is already relative and will try to relativize it further. Only a
+ * relative-path reference will be returned as-is.
+ *
+ * echo UriResolver::relativize($base, new Uri('/a/b/c')); // prints 'c' as well
+ */
+ public static function relativize(UriInterface $base, UriInterface $target) : UriInterface
+ {
+ if ($target->getScheme() !== '' && ($base->getScheme() !== $target->getScheme() || $target->getAuthority() === '' && $base->getAuthority() !== '')) {
+ return $target;
+ }
+ if (Uri::isRelativePathReference($target)) {
+ // As the target is already highly relative we return it as-is. It would be possible to resolve
+ // the target with `$target = self::resolve($base, $target);` and then try make it more relative
+ // by removing a duplicate query. But let's not do that automatically.
+ return $target;
+ }
+ if ($target->getAuthority() !== '' && $base->getAuthority() !== $target->getAuthority()) {
+ return $target->withScheme('');
+ }
+ // We must remove the path before removing the authority because if the path starts with two slashes, the URI
+ // would turn invalid. And we also cannot set a relative path before removing the authority, as that is also
+ // invalid.
+ $emptyPathUri = $target->withScheme('')->withPath('')->withUserInfo('')->withPort(null)->withHost('');
+ if ($base->getPath() !== $target->getPath()) {
+ return $emptyPathUri->withPath(self::getRelativePath($base, $target));
+ }
+ if ($base->getQuery() === $target->getQuery()) {
+ // Only the target fragment is left. And it must be returned even if base and target fragment are the same.
+ return $emptyPathUri->withQuery('');
+ }
+ // If the base URI has a query but the target has none, we cannot return an empty path reference as it would
+ // inherit the base query component when resolving.
+ if ($target->getQuery() === '') {
+ $segments = \explode('/', $target->getPath());
+ /** @var string $lastSegment */
+ $lastSegment = \end($segments);
+ return $emptyPathUri->withPath($lastSegment === '' ? './' : $lastSegment);
+ }
+ return $emptyPathUri;
+ }
+ private static function getRelativePath(UriInterface $base, UriInterface $target) : string
+ {
+ $sourceSegments = \explode('/', $base->getPath());
+ $targetSegments = \explode('/', $target->getPath());
+ \array_pop($sourceSegments);
+ $targetLastSegment = \array_pop($targetSegments);
+ foreach ($sourceSegments as $i => $segment) {
+ if (isset($targetSegments[$i]) && $segment === $targetSegments[$i]) {
+ unset($sourceSegments[$i], $targetSegments[$i]);
+ } else {
+ break;
+ }
+ }
+ $targetSegments[] = $targetLastSegment;
+ $relativePath = \str_repeat('../', \count($sourceSegments)) . \implode('/', $targetSegments);
+ // A reference to am empty last segment or an empty first sub-segment must be prefixed with "./".
+ // This also applies to a segment with a colon character (e.g., "file:colon") that cannot be used
+ // as the first segment of a relative-path reference, as it would be mistaken for a scheme name.
+ if ('' === $relativePath || \false !== \strpos(\explode('/', $relativePath, 2)[0], ':')) {
+ $relativePath = "./{$relativePath}";
+ } elseif ('/' === $relativePath[0]) {
+ if ($base->getAuthority() != '' && $base->getPath() === '') {
+ // In this case an extra slash is added by resolve() automatically. So we must not add one here.
+ $relativePath = ".{$relativePath}";
+ } else {
+ $relativePath = "./{$relativePath}";
+ }
+ }
+ return $relativePath;
+ }
+ private function __construct()
+ {
+ // cannot be instantiated
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/Utils.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/Utils.php
new file mode 100755
index 00000000..169b87f0
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/guzzlehttp/psr7/src/Utils.php
@@ -0,0 +1,386 @@
+ $v) {
+ if (!\in_array(\strtolower((string) $k), $keys)) {
+ $result[$k] = $v;
+ }
+ }
+ return $result;
+ }
+ /**
+ * Copy the contents of a stream into another stream until the given number
+ * of bytes have been read.
+ *
+ * @param StreamInterface $source Stream to read from
+ * @param StreamInterface $dest Stream to write to
+ * @param int $maxLen Maximum number of bytes to read. Pass -1
+ * to read the entire stream.
+ *
+ * @throws \RuntimeException on error.
+ */
+ public static function copyToStream(StreamInterface $source, StreamInterface $dest, int $maxLen = -1) : void
+ {
+ $bufferSize = 8192;
+ if ($maxLen === -1) {
+ while (!$source->eof()) {
+ if (!$dest->write($source->read($bufferSize))) {
+ break;
+ }
+ }
+ } else {
+ $remaining = $maxLen;
+ while ($remaining > 0 && !$source->eof()) {
+ $buf = $source->read(\min($bufferSize, $remaining));
+ $len = \strlen($buf);
+ if (!$len) {
+ break;
+ }
+ $remaining -= $len;
+ $dest->write($buf);
+ }
+ }
+ }
+ /**
+ * Copy the contents of a stream into a string until the given number of
+ * bytes have been read.
+ *
+ * @param StreamInterface $stream Stream to read
+ * @param int $maxLen Maximum number of bytes to read. Pass -1
+ * to read the entire stream.
+ *
+ * @throws \RuntimeException on error.
+ */
+ public static function copyToString(StreamInterface $stream, int $maxLen = -1) : string
+ {
+ $buffer = '';
+ if ($maxLen === -1) {
+ while (!$stream->eof()) {
+ $buf = $stream->read(1048576);
+ if ($buf === '') {
+ break;
+ }
+ $buffer .= $buf;
+ }
+ return $buffer;
+ }
+ $len = 0;
+ while (!$stream->eof() && $len < $maxLen) {
+ $buf = $stream->read($maxLen - $len);
+ if ($buf === '') {
+ break;
+ }
+ $buffer .= $buf;
+ $len = \strlen($buffer);
+ }
+ return $buffer;
+ }
+ /**
+ * Calculate a hash of a stream.
+ *
+ * This method reads the entire stream to calculate a rolling hash, based
+ * on PHP's `hash_init` functions.
+ *
+ * @param StreamInterface $stream Stream to calculate the hash for
+ * @param string $algo Hash algorithm (e.g. md5, crc32, etc)
+ * @param bool $rawOutput Whether or not to use raw output
+ *
+ * @throws \RuntimeException on error.
+ */
+ public static function hash(StreamInterface $stream, string $algo, bool $rawOutput = \false) : string
+ {
+ $pos = $stream->tell();
+ if ($pos > 0) {
+ $stream->rewind();
+ }
+ $ctx = \hash_init($algo);
+ while (!$stream->eof()) {
+ \hash_update($ctx, $stream->read(1048576));
+ }
+ $out = \hash_final($ctx, $rawOutput);
+ $stream->seek($pos);
+ return $out;
+ }
+ /**
+ * Clone and modify a request with the given changes.
+ *
+ * This method is useful for reducing the number of clones needed to mutate
+ * a message.
+ *
+ * The changes can be one of:
+ * - method: (string) Changes the HTTP method.
+ * - set_headers: (array) Sets the given headers.
+ * - remove_headers: (array) Remove the given headers.
+ * - body: (mixed) Sets the given body.
+ * - uri: (UriInterface) Set the URI.
+ * - query: (string) Set the query string value of the URI.
+ * - version: (string) Set the protocol version.
+ *
+ * @param RequestInterface $request Request to clone and modify.
+ * @param array $changes Changes to apply.
+ */
+ public static function modifyRequest(RequestInterface $request, array $changes) : RequestInterface
+ {
+ if (!$changes) {
+ return $request;
+ }
+ $headers = $request->getHeaders();
+ if (!isset($changes['uri'])) {
+ $uri = $request->getUri();
+ } else {
+ // Remove the host header if one is on the URI
+ if ($host = $changes['uri']->getHost()) {
+ $changes['set_headers']['Host'] = $host;
+ if ($port = $changes['uri']->getPort()) {
+ $standardPorts = ['http' => 80, 'https' => 443];
+ $scheme = $changes['uri']->getScheme();
+ if (isset($standardPorts[$scheme]) && $port != $standardPorts[$scheme]) {
+ $changes['set_headers']['Host'] .= ':' . $port;
+ }
+ }
+ }
+ $uri = $changes['uri'];
+ }
+ if (!empty($changes['remove_headers'])) {
+ $headers = self::caselessRemove($changes['remove_headers'], $headers);
+ }
+ if (!empty($changes['set_headers'])) {
+ $headers = self::caselessRemove(\array_keys($changes['set_headers']), $headers);
+ $headers = $changes['set_headers'] + $headers;
+ }
+ if (isset($changes['query'])) {
+ $uri = $uri->withQuery($changes['query']);
+ }
+ if ($request instanceof ServerRequestInterface) {
+ $new = (new ServerRequest($changes['method'] ?? $request->getMethod(), $uri, $headers, $changes['body'] ?? $request->getBody(), $changes['version'] ?? $request->getProtocolVersion(), $request->getServerParams()))->withParsedBody($request->getParsedBody())->withQueryParams($request->getQueryParams())->withCookieParams($request->getCookieParams())->withUploadedFiles($request->getUploadedFiles());
+ foreach ($request->getAttributes() as $key => $value) {
+ $new = $new->withAttribute($key, $value);
+ }
+ return $new;
+ }
+ return new Request($changes['method'] ?? $request->getMethod(), $uri, $headers, $changes['body'] ?? $request->getBody(), $changes['version'] ?? $request->getProtocolVersion());
+ }
+ /**
+ * Read a line from the stream up to the maximum allowed buffer length.
+ *
+ * @param StreamInterface $stream Stream to read from
+ * @param int|null $maxLength Maximum buffer length
+ */
+ public static function readLine(StreamInterface $stream, ?int $maxLength = null) : string
+ {
+ $buffer = '';
+ $size = 0;
+ while (!$stream->eof()) {
+ if ('' === ($byte = $stream->read(1))) {
+ return $buffer;
+ }
+ $buffer .= $byte;
+ // Break when a new line is found or the max length - 1 is reached
+ if ($byte === "\n" || ++$size === $maxLength - 1) {
+ break;
+ }
+ }
+ return $buffer;
+ }
+ /**
+ * Redact the password in the user info part of a URI.
+ */
+ public static function redactUserInfo(UriInterface $uri) : UriInterface
+ {
+ $userInfo = $uri->getUserInfo();
+ if (\false !== ($pos = \strpos($userInfo, ':'))) {
+ return $uri->withUserInfo(\substr($userInfo, 0, $pos), '***');
+ }
+ return $uri;
+ }
+ /**
+ * Create a new stream based on the input type.
+ *
+ * Options is an associative array that can contain the following keys:
+ * - metadata: Array of custom metadata.
+ * - size: Size of the stream.
+ *
+ * This method accepts the following `$resource` types:
+ * - `Psr\Http\Message\StreamInterface`: Returns the value as-is.
+ * - `string`: Creates a stream object that uses the given string as the contents.
+ * - `resource`: Creates a stream object that wraps the given PHP stream resource.
+ * - `Iterator`: If the provided value implements `Iterator`, then a read-only
+ * stream object will be created that wraps the given iterable. Each time the
+ * stream is read from, data from the iterator will fill a buffer and will be
+ * continuously called until the buffer is equal to the requested read size.
+ * Subsequent read calls will first read from the buffer and then call `next`
+ * on the underlying iterator until it is exhausted.
+ * - `object` with `__toString()`: If the object has the `__toString()` method,
+ * the object will be cast to a string and then a stream will be returned that
+ * uses the string value.
+ * - `NULL`: When `null` is passed, an empty stream object is returned.
+ * - `callable` When a callable is passed, a read-only stream object will be
+ * created that invokes the given callable. The callable is invoked with the
+ * number of suggested bytes to read. The callable can return any number of
+ * bytes, but MUST return `false` when there is no more data to return. The
+ * stream object that wraps the callable will invoke the callable until the
+ * number of requested bytes are available. Any additional bytes will be
+ * buffered and used in subsequent reads.
+ *
+ * @param resource|string|int|float|bool|StreamInterface|callable|\Iterator|null $resource Entity body data
+ * @param array{size?: int, metadata?: array} $options Additional options
+ *
+ * @throws \InvalidArgumentException if the $resource arg is not valid.
+ */
+ public static function streamFor($resource = '', array $options = []) : StreamInterface
+ {
+ if (\is_scalar($resource)) {
+ $stream = self::tryFopen('php://temp', 'r+');
+ if ($resource !== '') {
+ \fwrite($stream, (string) $resource);
+ \fseek($stream, 0);
+ }
+ return new Stream($stream, $options);
+ }
+ switch (\gettype($resource)) {
+ case 'resource':
+ /*
+ * The 'php://input' is a special stream with quirks and inconsistencies.
+ * We avoid using that stream by reading it into php://temp
+ */
+ /** @var resource $resource */
+ if ((\stream_get_meta_data($resource)['uri'] ?? '') === 'php://input') {
+ $stream = self::tryFopen('php://temp', 'w+');
+ \stream_copy_to_stream($resource, $stream);
+ \fseek($stream, 0);
+ $resource = $stream;
+ }
+ return new Stream($resource, $options);
+ case 'object':
+ /** @var object $resource */
+ if ($resource instanceof StreamInterface) {
+ return $resource;
+ } elseif ($resource instanceof \Iterator) {
+ return new PumpStream(function () use($resource) {
+ if (!$resource->valid()) {
+ return \false;
+ }
+ $result = $resource->current();
+ $resource->next();
+ return $result;
+ }, $options);
+ } elseif (\method_exists($resource, '__toString')) {
+ return self::streamFor((string) $resource, $options);
+ }
+ break;
+ case 'NULL':
+ return new Stream(self::tryFopen('php://temp', 'r+'), $options);
+ }
+ if (\is_callable($resource)) {
+ return new PumpStream($resource, $options);
+ }
+ throw new \InvalidArgumentException('Invalid resource type: ' . \gettype($resource));
+ }
+ /**
+ * Safely opens a PHP stream resource using a filename.
+ *
+ * When fopen fails, PHP normally raises a warning. This function adds an
+ * error handler that checks for errors and throws an exception instead.
+ *
+ * @param string $filename File to open
+ * @param string $mode Mode used to open the file
+ *
+ * @return resource
+ *
+ * @throws \RuntimeException if the file cannot be opened
+ */
+ public static function tryFopen(string $filename, string $mode)
+ {
+ $ex = null;
+ \set_error_handler(static function (int $errno, string $errstr) use($filename, $mode, &$ex) : bool {
+ $ex = new \RuntimeException(\sprintf('Unable to open "%s" using mode "%s": %s', $filename, $mode, $errstr));
+ return \true;
+ });
+ try {
+ /** @var resource $handle */
+ $handle = \fopen($filename, $mode);
+ } catch (\Throwable $e) {
+ $ex = new \RuntimeException(\sprintf('Unable to open "%s" using mode "%s": %s', $filename, $mode, $e->getMessage()), 0, $e);
+ }
+ \restore_error_handler();
+ if ($ex) {
+ /** @var \RuntimeException $ex */
+ throw $ex;
+ }
+ return $handle;
+ }
+ /**
+ * Safely gets the contents of a given stream.
+ *
+ * When stream_get_contents fails, PHP normally raises a warning. This
+ * function adds an error handler that checks for errors and throws an
+ * exception instead.
+ *
+ * @param resource $stream
+ *
+ * @throws \RuntimeException if the stream cannot be read
+ */
+ public static function tryGetContents($stream) : string
+ {
+ $ex = null;
+ \set_error_handler(static function (int $errno, string $errstr) use(&$ex) : bool {
+ $ex = new \RuntimeException(\sprintf('Unable to read stream contents: %s', $errstr));
+ return \true;
+ });
+ try {
+ /** @var string|false $contents */
+ $contents = \stream_get_contents($stream);
+ if ($contents === \false) {
+ $ex = new \RuntimeException('Unable to read stream contents');
+ }
+ } catch (\Throwable $e) {
+ $ex = new \RuntimeException(\sprintf('Unable to read stream contents: %s', $e->getMessage()), 0, $e);
+ }
+ \restore_error_handler();
+ if ($ex) {
+ /** @var \RuntimeException $ex */
+ throw $ex;
+ }
+ return $contents;
+ }
+ /**
+ * Returns a UriInterface for the given value.
+ *
+ * This function accepts a string or UriInterface and returns a
+ * UriInterface for the given value. If the value is already a
+ * UriInterface, it is returned as-is.
+ *
+ * @param string|UriInterface $uri
+ *
+ * @throws \InvalidArgumentException
+ */
+ public static function uriFor($uri) : UriInterface
+ {
+ if ($uri instanceof UriInterface) {
+ return $uri;
+ }
+ if (\is_string($uri)) {
+ return new Uri($uri);
+ }
+ throw new \InvalidArgumentException('URI must be a string or UriInterface');
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/paragonie/constant_time_encoding/LICENSE.txt b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/paragonie/constant_time_encoding/LICENSE.txt
new file mode 100755
index 00000000..91acaca6
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/paragonie/constant_time_encoding/LICENSE.txt
@@ -0,0 +1,48 @@
+The MIT License (MIT)
+
+Copyright (c) 2016 - 2022 Paragon Initiative Enterprises
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+------------------------------------------------------------------------------
+This library was based on the work of Steve "Sc00bz" Thomas.
+------------------------------------------------------------------------------
+
+The MIT License (MIT)
+
+Copyright (c) 2014 Steve Thomas
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/paragonie/constant_time_encoding/src/Base32.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/paragonie/constant_time_encoding/src/Base32.php
new file mode 100755
index 00000000..1a0f580f
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/paragonie/constant_time_encoding/src/Base32.php
@@ -0,0 +1,440 @@
+ 96 && $src < 123) $ret += $src - 97 + 1; // -64
+ $ret += (0x60 - $src & $src - 0x7b) >> 8 & $src - 96;
+ // if ($src > 0x31 && $src < 0x38) $ret += $src - 24 + 1; // -23
+ $ret += (0x31 - $src & $src - 0x38) >> 8 & $src - 23;
+ return $ret;
+ }
+ /**
+ * Uses bitwise operators instead of table-lookups to turn 5-bit integers
+ * into 8-bit integers.
+ *
+ * Uppercase variant.
+ *
+ * @param int $src
+ * @return int
+ */
+ protected static function decode5BitsUpper(int $src) : int
+ {
+ $ret = -1;
+ // if ($src > 64 && $src < 91) $ret += $src - 65 + 1; // -64
+ $ret += (0x40 - $src & $src - 0x5b) >> 8 & $src - 64;
+ // if ($src > 0x31 && $src < 0x38) $ret += $src - 24 + 1; // -23
+ $ret += (0x31 - $src & $src - 0x38) >> 8 & $src - 23;
+ return $ret;
+ }
+ /**
+ * Uses bitwise operators instead of table-lookups to turn 8-bit integers
+ * into 5-bit integers.
+ *
+ * @param int $src
+ * @return string
+ */
+ protected static function encode5Bits(int $src) : string
+ {
+ $diff = 0x61;
+ // if ($src > 25) $ret -= 72;
+ $diff -= 25 - $src >> 8 & 73;
+ return pack('C', $src + $diff);
+ }
+ /**
+ * Uses bitwise operators instead of table-lookups to turn 8-bit integers
+ * into 5-bit integers.
+ *
+ * Uppercase variant.
+ *
+ * @param int $src
+ * @return string
+ */
+ protected static function encode5BitsUpper(int $src) : string
+ {
+ $diff = 0x41;
+ // if ($src > 25) $ret -= 40;
+ $diff -= 25 - $src >> 8 & 41;
+ return pack('C', $src + $diff);
+ }
+ /**
+ * @param string $encodedString
+ * @param bool $upper
+ * @return string
+ */
+ public static function decodeNoPadding(
+ #[SensitiveParameter]
+ string $encodedString,
+ bool $upper = \false
+ ) : string
+ {
+ $srcLen = Binary::safeStrlen($encodedString);
+ if ($srcLen === 0) {
+ return '';
+ }
+ if (($srcLen & 7) === 0) {
+ for ($j = 0; $j < 7 && $j < $srcLen; ++$j) {
+ if ($encodedString[$srcLen - $j - 1] === '=') {
+ throw new InvalidArgumentException("decodeNoPadding() doesn't tolerate padding");
+ }
+ }
+ }
+ return static::doDecode($encodedString, $upper, \true);
+ }
+ /**
+ * Base32 decoding
+ *
+ * @param string $src
+ * @param bool $upper
+ * @param bool $strictPadding
+ * @return string
+ *
+ * @throws TypeError
+ */
+ protected static function doDecode(
+ #[SensitiveParameter]
+ string $src,
+ bool $upper = \false,
+ bool $strictPadding = \false
+ ) : string
+ {
+ // We do this to reduce code duplication:
+ $method = $upper ? 'decode5BitsUpper' : 'decode5Bits';
+ // Remove padding
+ $srcLen = Binary::safeStrlen($src);
+ if ($srcLen === 0) {
+ return '';
+ }
+ if ($strictPadding) {
+ if (($srcLen & 7) === 0) {
+ for ($j = 0; $j < 7; ++$j) {
+ if ($src[$srcLen - 1] === '=') {
+ $srcLen--;
+ } else {
+ break;
+ }
+ }
+ }
+ if (($srcLen & 7) === 1) {
+ throw new RangeException('Incorrect padding');
+ }
+ } else {
+ $src = \rtrim($src, '=');
+ $srcLen = Binary::safeStrlen($src);
+ }
+ $err = 0;
+ $dest = '';
+ // Main loop (no padding):
+ for ($i = 0; $i + 8 <= $srcLen; $i += 8) {
+ /** @var array $chunk */
+ $chunk = unpack('C*', Binary::safeSubstr($src, $i, 8));
+ /** @var int $c0 */
+ $c0 = static::$method($chunk[1]);
+ /** @var int $c1 */
+ $c1 = static::$method($chunk[2]);
+ /** @var int $c2 */
+ $c2 = static::$method($chunk[3]);
+ /** @var int $c3 */
+ $c3 = static::$method($chunk[4]);
+ /** @var int $c4 */
+ $c4 = static::$method($chunk[5]);
+ /** @var int $c5 */
+ $c5 = static::$method($chunk[6]);
+ /** @var int $c6 */
+ $c6 = static::$method($chunk[7]);
+ /** @var int $c7 */
+ $c7 = static::$method($chunk[8]);
+ $dest .= pack('CCCCC', ($c0 << 3 | $c1 >> 2) & 0xff, ($c1 << 6 | $c2 << 1 | $c3 >> 4) & 0xff, ($c3 << 4 | $c4 >> 1) & 0xff, ($c4 << 7 | $c5 << 2 | $c6 >> 3) & 0xff, ($c6 << 5 | $c7) & 0xff);
+ $err |= ($c0 | $c1 | $c2 | $c3 | $c4 | $c5 | $c6 | $c7) >> 8;
+ }
+ // The last chunk, which may have padding:
+ if ($i < $srcLen) {
+ /** @var array $chunk */
+ $chunk = unpack('C*', Binary::safeSubstr($src, $i, $srcLen - $i));
+ /** @var int $c0 */
+ $c0 = static::$method($chunk[1]);
+ if ($i + 6 < $srcLen) {
+ /** @var int $c1 */
+ $c1 = static::$method($chunk[2]);
+ /** @var int $c2 */
+ $c2 = static::$method($chunk[3]);
+ /** @var int $c3 */
+ $c3 = static::$method($chunk[4]);
+ /** @var int $c4 */
+ $c4 = static::$method($chunk[5]);
+ /** @var int $c5 */
+ $c5 = static::$method($chunk[6]);
+ /** @var int $c6 */
+ $c6 = static::$method($chunk[7]);
+ $dest .= pack('CCCC', ($c0 << 3 | $c1 >> 2) & 0xff, ($c1 << 6 | $c2 << 1 | $c3 >> 4) & 0xff, ($c3 << 4 | $c4 >> 1) & 0xff, ($c4 << 7 | $c5 << 2 | $c6 >> 3) & 0xff);
+ $err |= ($c0 | $c1 | $c2 | $c3 | $c4 | $c5 | $c6) >> 8;
+ if ($strictPadding) {
+ $err |= $c6 << 5 & 0xff;
+ }
+ } elseif ($i + 5 < $srcLen) {
+ /** @var int $c1 */
+ $c1 = static::$method($chunk[2]);
+ /** @var int $c2 */
+ $c2 = static::$method($chunk[3]);
+ /** @var int $c3 */
+ $c3 = static::$method($chunk[4]);
+ /** @var int $c4 */
+ $c4 = static::$method($chunk[5]);
+ /** @var int $c5 */
+ $c5 = static::$method($chunk[6]);
+ $dest .= pack('CCCC', ($c0 << 3 | $c1 >> 2) & 0xff, ($c1 << 6 | $c2 << 1 | $c3 >> 4) & 0xff, ($c3 << 4 | $c4 >> 1) & 0xff, ($c4 << 7 | $c5 << 2) & 0xff);
+ $err |= ($c0 | $c1 | $c2 | $c3 | $c4 | $c5) >> 8;
+ } elseif ($i + 4 < $srcLen) {
+ /** @var int $c1 */
+ $c1 = static::$method($chunk[2]);
+ /** @var int $c2 */
+ $c2 = static::$method($chunk[3]);
+ /** @var int $c3 */
+ $c3 = static::$method($chunk[4]);
+ /** @var int $c4 */
+ $c4 = static::$method($chunk[5]);
+ $dest .= pack('CCC', ($c0 << 3 | $c1 >> 2) & 0xff, ($c1 << 6 | $c2 << 1 | $c3 >> 4) & 0xff, ($c3 << 4 | $c4 >> 1) & 0xff);
+ $err |= ($c0 | $c1 | $c2 | $c3 | $c4) >> 8;
+ if ($strictPadding) {
+ $err |= $c4 << 7 & 0xff;
+ }
+ } elseif ($i + 3 < $srcLen) {
+ /** @var int $c1 */
+ $c1 = static::$method($chunk[2]);
+ /** @var int $c2 */
+ $c2 = static::$method($chunk[3]);
+ /** @var int $c3 */
+ $c3 = static::$method($chunk[4]);
+ $dest .= pack('CC', ($c0 << 3 | $c1 >> 2) & 0xff, ($c1 << 6 | $c2 << 1 | $c3 >> 4) & 0xff);
+ $err |= ($c0 | $c1 | $c2 | $c3) >> 8;
+ if ($strictPadding) {
+ $err |= $c3 << 4 & 0xff;
+ }
+ } elseif ($i + 2 < $srcLen) {
+ /** @var int $c1 */
+ $c1 = static::$method($chunk[2]);
+ /** @var int $c2 */
+ $c2 = static::$method($chunk[3]);
+ $dest .= pack('CC', ($c0 << 3 | $c1 >> 2) & 0xff, ($c1 << 6 | $c2 << 1) & 0xff);
+ $err |= ($c0 | $c1 | $c2) >> 8;
+ if ($strictPadding) {
+ $err |= $c2 << 6 & 0xff;
+ }
+ } elseif ($i + 1 < $srcLen) {
+ /** @var int $c1 */
+ $c1 = static::$method($chunk[2]);
+ $dest .= pack('C', ($c0 << 3 | $c1 >> 2) & 0xff);
+ $err |= ($c0 | $c1) >> 8;
+ if ($strictPadding) {
+ $err |= $c1 << 6 & 0xff;
+ }
+ } else {
+ $dest .= pack('C', $c0 << 3 & 0xff);
+ $err |= $c0 >> 8;
+ }
+ }
+ $check = $err === 0;
+ if (!$check) {
+ throw new RangeException('Base32::doDecode() only expects characters in the correct base32 alphabet');
+ }
+ return $dest;
+ }
+ /**
+ * Base32 Encoding
+ *
+ * @param string $src
+ * @param bool $upper
+ * @param bool $pad
+ * @return string
+ * @throws TypeError
+ */
+ protected static function doEncode(
+ #[SensitiveParameter]
+ string $src,
+ bool $upper = \false,
+ $pad = \true
+ ) : string
+ {
+ // We do this to reduce code duplication:
+ $method = $upper ? 'encode5BitsUpper' : 'encode5Bits';
+ $dest = '';
+ $srcLen = Binary::safeStrlen($src);
+ // Main loop (no padding):
+ for ($i = 0; $i + 5 <= $srcLen; $i += 5) {
+ /** @var array $chunk */
+ $chunk = unpack('C*', Binary::safeSubstr($src, $i, 5));
+ $b0 = $chunk[1];
+ $b1 = $chunk[2];
+ $b2 = $chunk[3];
+ $b3 = $chunk[4];
+ $b4 = $chunk[5];
+ $dest .= static::$method($b0 >> 3 & 31) . static::$method(($b0 << 2 | $b1 >> 6) & 31) . static::$method($b1 >> 1 & 31) . static::$method(($b1 << 4 | $b2 >> 4) & 31) . static::$method(($b2 << 1 | $b3 >> 7) & 31) . static::$method($b3 >> 2 & 31) . static::$method(($b3 << 3 | $b4 >> 5) & 31) . static::$method($b4 & 31);
+ }
+ // The last chunk, which may have padding:
+ if ($i < $srcLen) {
+ /** @var array $chunk */
+ $chunk = unpack('C*', Binary::safeSubstr($src, $i, $srcLen - $i));
+ $b0 = $chunk[1];
+ if ($i + 3 < $srcLen) {
+ $b1 = $chunk[2];
+ $b2 = $chunk[3];
+ $b3 = $chunk[4];
+ $dest .= static::$method($b0 >> 3 & 31) . static::$method(($b0 << 2 | $b1 >> 6) & 31) . static::$method($b1 >> 1 & 31) . static::$method(($b1 << 4 | $b2 >> 4) & 31) . static::$method(($b2 << 1 | $b3 >> 7) & 31) . static::$method($b3 >> 2 & 31) . static::$method($b3 << 3 & 31);
+ if ($pad) {
+ $dest .= '=';
+ }
+ } elseif ($i + 2 < $srcLen) {
+ $b1 = $chunk[2];
+ $b2 = $chunk[3];
+ $dest .= static::$method($b0 >> 3 & 31) . static::$method(($b0 << 2 | $b1 >> 6) & 31) . static::$method($b1 >> 1 & 31) . static::$method(($b1 << 4 | $b2 >> 4) & 31) . static::$method($b2 << 1 & 31);
+ if ($pad) {
+ $dest .= '===';
+ }
+ } elseif ($i + 1 < $srcLen) {
+ $b1 = $chunk[2];
+ $dest .= static::$method($b0 >> 3 & 31) . static::$method(($b0 << 2 | $b1 >> 6) & 31) . static::$method($b1 >> 1 & 31) . static::$method($b1 << 4 & 31);
+ if ($pad) {
+ $dest .= '====';
+ }
+ } else {
+ $dest .= static::$method($b0 >> 3 & 31) . static::$method($b0 << 2 & 31);
+ if ($pad) {
+ $dest .= '======';
+ }
+ }
+ }
+ return $dest;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/paragonie/constant_time_encoding/src/Base32Hex.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/paragonie/constant_time_encoding/src/Base32Hex.php
new file mode 100755
index 00000000..b1b26472
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/paragonie/constant_time_encoding/src/Base32Hex.php
@@ -0,0 +1,99 @@
+ 0x30 && $src < 0x3a) ret += $src - 0x2e + 1; // -47
+ $ret += (0x2f - $src & $src - 0x3a) >> 8 & $src - 47;
+ // if ($src > 0x60 && $src < 0x77) ret += $src - 0x61 + 10 + 1; // -86
+ $ret += (0x60 - $src & $src - 0x77) >> 8 & $src - 86;
+ return $ret;
+ }
+ /**
+ * Uses bitwise operators instead of table-lookups to turn 5-bit integers
+ * into 8-bit integers.
+ *
+ * @param int $src
+ * @return int
+ */
+ protected static function decode5BitsUpper(int $src) : int
+ {
+ $ret = -1;
+ // if ($src > 0x30 && $src < 0x3a) ret += $src - 0x2e + 1; // -47
+ $ret += (0x2f - $src & $src - 0x3a) >> 8 & $src - 47;
+ // if ($src > 0x40 && $src < 0x57) ret += $src - 0x41 + 10 + 1; // -54
+ $ret += (0x40 - $src & $src - 0x57) >> 8 & $src - 54;
+ return $ret;
+ }
+ /**
+ * Uses bitwise operators instead of table-lookups to turn 8-bit integers
+ * into 5-bit integers.
+ *
+ * @param int $src
+ * @return string
+ */
+ protected static function encode5Bits(int $src) : string
+ {
+ $src += 0x30;
+ // if ($src > 0x39) $src += 0x61 - 0x3a; // 39
+ $src += 0x39 - $src >> 8 & 39;
+ return pack('C', $src);
+ }
+ /**
+ * Uses bitwise operators instead of table-lookups to turn 8-bit integers
+ * into 5-bit integers.
+ *
+ * Uppercase variant.
+ *
+ * @param int $src
+ * @return string
+ */
+ protected static function encode5BitsUpper(int $src) : string
+ {
+ $src += 0x30;
+ // if ($src > 0x39) $src += 0x41 - 0x3a; // 7
+ $src += 0x39 - $src >> 8 & 7;
+ return pack('C', $src);
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/paragonie/constant_time_encoding/src/Base64.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/paragonie/constant_time_encoding/src/Base64.php
new file mode 100755
index 00000000..ddcc0c34
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/paragonie/constant_time_encoding/src/Base64.php
@@ -0,0 +1,338 @@
+ 0) {
+ try {
+ return sodium_bin2base64($binString, $variant);
+ } catch (SodiumException $ex) {
+ throw new RangeException($ex->getMessage(), $ex->getCode(), $ex);
+ }
+ }
+ }
+ return static::doEncode($binString, \true);
+ }
+ /**
+ * Encode into Base64, no = padding
+ *
+ * Base64 character set "[A-Z][a-z][0-9]+/"
+ *
+ * @param string $src
+ * @return string
+ *
+ * @throws TypeError
+ */
+ public static function encodeUnpadded(
+ #[SensitiveParameter]
+ string $src
+ ) : string
+ {
+ if (extension_loaded('sodium')) {
+ switch (static::class) {
+ case Base64::class:
+ $variant = SODIUM_BASE64_VARIANT_ORIGINAL_NO_PADDING;
+ break;
+ case Base64UrlSafe::class:
+ $variant = SODIUM_BASE64_VARIANT_URLSAFE_NO_PADDING;
+ break;
+ default:
+ $variant = 0;
+ }
+ if ($variant > 0) {
+ try {
+ return sodium_bin2base64($src, $variant);
+ } catch (SodiumException $ex) {
+ throw new RangeException($ex->getMessage(), $ex->getCode(), $ex);
+ }
+ }
+ }
+ return static::doEncode($src, \false);
+ }
+ /**
+ * @param string $src
+ * @param bool $pad Include = padding?
+ * @return string
+ *
+ * @throws TypeError
+ */
+ protected static function doEncode(
+ #[SensitiveParameter]
+ string $src,
+ bool $pad = \true
+ ) : string
+ {
+ $dest = '';
+ $srcLen = Binary::safeStrlen($src);
+ // Main loop (no padding):
+ for ($i = 0; $i + 3 <= $srcLen; $i += 3) {
+ /** @var array $chunk */
+ $chunk = unpack('C*', Binary::safeSubstr($src, $i, 3));
+ $b0 = $chunk[1];
+ $b1 = $chunk[2];
+ $b2 = $chunk[3];
+ $dest .= static::encode6Bits($b0 >> 2) . static::encode6Bits(($b0 << 4 | $b1 >> 4) & 63) . static::encode6Bits(($b1 << 2 | $b2 >> 6) & 63) . static::encode6Bits($b2 & 63);
+ }
+ // The last chunk, which may have padding:
+ if ($i < $srcLen) {
+ /** @var array $chunk */
+ $chunk = unpack('C*', Binary::safeSubstr($src, $i, $srcLen - $i));
+ $b0 = $chunk[1];
+ if ($i + 1 < $srcLen) {
+ $b1 = $chunk[2];
+ $dest .= static::encode6Bits($b0 >> 2) . static::encode6Bits(($b0 << 4 | $b1 >> 4) & 63) . static::encode6Bits($b1 << 2 & 63);
+ if ($pad) {
+ $dest .= '=';
+ }
+ } else {
+ $dest .= static::encode6Bits($b0 >> 2) . static::encode6Bits($b0 << 4 & 63);
+ if ($pad) {
+ $dest .= '==';
+ }
+ }
+ }
+ return $dest;
+ }
+ /**
+ * decode from base64 into binary
+ *
+ * Base64 character set "./[A-Z][a-z][0-9]"
+ *
+ * @param string $encodedString
+ * @param bool $strictPadding
+ * @return string
+ *
+ * @throws RangeException
+ * @throws TypeError
+ */
+ public static function decode(
+ #[SensitiveParameter]
+ string $encodedString,
+ bool $strictPadding = \false
+ ) : string
+ {
+ // Remove padding
+ $srcLen = Binary::safeStrlen($encodedString);
+ if ($srcLen === 0) {
+ return '';
+ }
+ if ($strictPadding) {
+ if (($srcLen & 3) === 0) {
+ if ($encodedString[$srcLen - 1] === '=') {
+ $srcLen--;
+ if ($encodedString[$srcLen - 1] === '=') {
+ $srcLen--;
+ }
+ }
+ }
+ if (($srcLen & 3) === 1) {
+ throw new RangeException('Incorrect padding');
+ }
+ if ($encodedString[$srcLen - 1] === '=') {
+ throw new RangeException('Incorrect padding');
+ }
+ if (extension_loaded('sodium')) {
+ switch (static::class) {
+ case Base64::class:
+ $variant = SODIUM_BASE64_VARIANT_ORIGINAL_NO_PADDING;
+ break;
+ case Base64UrlSafe::class:
+ $variant = SODIUM_BASE64_VARIANT_URLSAFE_NO_PADDING;
+ break;
+ default:
+ $variant = 0;
+ }
+ if ($variant > 0) {
+ try {
+ return sodium_base642bin(Binary::safeSubstr($encodedString, 0, $srcLen), $variant);
+ } catch (SodiumException $ex) {
+ throw new RangeException($ex->getMessage(), $ex->getCode(), $ex);
+ }
+ }
+ }
+ } else {
+ $encodedString = rtrim($encodedString, '=');
+ $srcLen = Binary::safeStrlen($encodedString);
+ }
+ $err = 0;
+ $dest = '';
+ // Main loop (no padding):
+ for ($i = 0; $i + 4 <= $srcLen; $i += 4) {
+ /** @var array $chunk */
+ $chunk = unpack('C*', Binary::safeSubstr($encodedString, $i, 4));
+ $c0 = static::decode6Bits($chunk[1]);
+ $c1 = static::decode6Bits($chunk[2]);
+ $c2 = static::decode6Bits($chunk[3]);
+ $c3 = static::decode6Bits($chunk[4]);
+ $dest .= pack('CCC', ($c0 << 2 | $c1 >> 4) & 0xff, ($c1 << 4 | $c2 >> 2) & 0xff, ($c2 << 6 | $c3) & 0xff);
+ $err |= ($c0 | $c1 | $c2 | $c3) >> 8;
+ }
+ // The last chunk, which may have padding:
+ if ($i < $srcLen) {
+ /** @var array $chunk */
+ $chunk = unpack('C*', Binary::safeSubstr($encodedString, $i, $srcLen - $i));
+ $c0 = static::decode6Bits($chunk[1]);
+ if ($i + 2 < $srcLen) {
+ $c1 = static::decode6Bits($chunk[2]);
+ $c2 = static::decode6Bits($chunk[3]);
+ $dest .= pack('CC', ($c0 << 2 | $c1 >> 4) & 0xff, ($c1 << 4 | $c2 >> 2) & 0xff);
+ $err |= ($c0 | $c1 | $c2) >> 8;
+ if ($strictPadding) {
+ $err |= $c2 << 6 & 0xff;
+ }
+ } elseif ($i + 1 < $srcLen) {
+ $c1 = static::decode6Bits($chunk[2]);
+ $dest .= pack('C', ($c0 << 2 | $c1 >> 4) & 0xff);
+ $err |= ($c0 | $c1) >> 8;
+ if ($strictPadding) {
+ $err |= $c1 << 4 & 0xff;
+ }
+ } elseif ($strictPadding) {
+ $err |= 1;
+ }
+ }
+ $check = $err === 0;
+ if (!$check) {
+ throw new RangeException('Base64::decode() only expects characters in the correct base64 alphabet');
+ }
+ return $dest;
+ }
+ /**
+ * @param string $encodedString
+ * @return string
+ */
+ public static function decodeNoPadding(
+ #[SensitiveParameter]
+ string $encodedString
+ ) : string
+ {
+ $srcLen = Binary::safeStrlen($encodedString);
+ if ($srcLen === 0) {
+ return '';
+ }
+ if (($srcLen & 3) === 0) {
+ // If $strLen is not zero, and it is divisible by 4, then it's at least 4.
+ if ($encodedString[$srcLen - 1] === '=' || $encodedString[$srcLen - 2] === '=') {
+ throw new InvalidArgumentException("decodeNoPadding() doesn't tolerate padding");
+ }
+ }
+ return static::decode($encodedString, \true);
+ }
+ /**
+ * Uses bitwise operators instead of table-lookups to turn 6-bit integers
+ * into 8-bit integers.
+ *
+ * Base64 character set:
+ * [A-Z] [a-z] [0-9] + /
+ * 0x41-0x5a, 0x61-0x7a, 0x30-0x39, 0x2b, 0x2f
+ *
+ * @param int $src
+ * @return int
+ */
+ protected static function decode6Bits(int $src) : int
+ {
+ $ret = -1;
+ // if ($src > 0x40 && $src < 0x5b) $ret += $src - 0x41 + 1; // -64
+ $ret += (0x40 - $src & $src - 0x5b) >> 8 & $src - 64;
+ // if ($src > 0x60 && $src < 0x7b) $ret += $src - 0x61 + 26 + 1; // -70
+ $ret += (0x60 - $src & $src - 0x7b) >> 8 & $src - 70;
+ // if ($src > 0x2f && $src < 0x3a) $ret += $src - 0x30 + 52 + 1; // 5
+ $ret += (0x2f - $src & $src - 0x3a) >> 8 & $src + 5;
+ // if ($src == 0x2b) $ret += 62 + 1;
+ $ret += (0x2a - $src & $src - 0x2c) >> 8 & 63;
+ // if ($src == 0x2f) ret += 63 + 1;
+ $ret += (0x2e - $src & $src - 0x30) >> 8 & 64;
+ return $ret;
+ }
+ /**
+ * Uses bitwise operators instead of table-lookups to turn 8-bit integers
+ * into 6-bit integers.
+ *
+ * @param int $src
+ * @return string
+ */
+ protected static function encode6Bits(int $src) : string
+ {
+ $diff = 0x41;
+ // if ($src > 25) $diff += 0x61 - 0x41 - 26; // 6
+ $diff += 25 - $src >> 8 & 6;
+ // if ($src > 51) $diff += 0x30 - 0x61 - 26; // -75
+ $diff -= 51 - $src >> 8 & 75;
+ // if ($src > 61) $diff += 0x2b - 0x30 - 10; // -15
+ $diff -= 61 - $src >> 8 & 15;
+ // if ($src > 62) $diff += 0x2f - 0x2b - 1; // 3
+ $diff += 62 - $src >> 8 & 3;
+ return pack('C', $src + $diff);
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/paragonie/constant_time_encoding/src/Base64DotSlash.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/paragonie/constant_time_encoding/src/Base64DotSlash.php
new file mode 100755
index 00000000..7154b2b0
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/paragonie/constant_time_encoding/src/Base64DotSlash.php
@@ -0,0 +1,79 @@
+ 0x2d && $src < 0x30) ret += $src - 0x2e + 1; // -45
+ $ret += (0x2d - $src & $src - 0x30) >> 8 & $src - 45;
+ // if ($src > 0x40 && $src < 0x5b) ret += $src - 0x41 + 2 + 1; // -62
+ $ret += (0x40 - $src & $src - 0x5b) >> 8 & $src - 62;
+ // if ($src > 0x60 && $src < 0x7b) ret += $src - 0x61 + 28 + 1; // -68
+ $ret += (0x60 - $src & $src - 0x7b) >> 8 & $src - 68;
+ // if ($src > 0x2f && $src < 0x3a) ret += $src - 0x30 + 54 + 1; // 7
+ $ret += (0x2f - $src & $src - 0x3a) >> 8 & $src + 7;
+ return $ret;
+ }
+ /**
+ * Uses bitwise operators instead of table-lookups to turn 8-bit integers
+ * into 6-bit integers.
+ *
+ * @param int $src
+ * @return string
+ */
+ protected static function encode6Bits(int $src) : string
+ {
+ $src += 0x2e;
+ // if ($src > 0x2f) $src += 0x41 - 0x30; // 17
+ $src += 0x2f - $src >> 8 & 17;
+ // if ($src > 0x5a) $src += 0x61 - 0x5b; // 6
+ $src += 0x5a - $src >> 8 & 6;
+ // if ($src > 0x7a) $src += 0x30 - 0x7b; // -75
+ $src -= 0x7a - $src >> 8 & 75;
+ return pack('C', $src);
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/paragonie/constant_time_encoding/src/Base64DotSlashOrdered.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/paragonie/constant_time_encoding/src/Base64DotSlashOrdered.php
new file mode 100755
index 00000000..a5963475
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/paragonie/constant_time_encoding/src/Base64DotSlashOrdered.php
@@ -0,0 +1,75 @@
+ 0x2d && $src < 0x3a) ret += $src - 0x2e + 1; // -45
+ $ret += (0x2d - $src & $src - 0x3a) >> 8 & $src - 45;
+ // if ($src > 0x40 && $src < 0x5b) ret += $src - 0x41 + 12 + 1; // -52
+ $ret += (0x40 - $src & $src - 0x5b) >> 8 & $src - 52;
+ // if ($src > 0x60 && $src < 0x7b) ret += $src - 0x61 + 38 + 1; // -58
+ $ret += (0x60 - $src & $src - 0x7b) >> 8 & $src - 58;
+ return $ret;
+ }
+ /**
+ * Uses bitwise operators instead of table-lookups to turn 8-bit integers
+ * into 6-bit integers.
+ *
+ * @param int $src
+ * @return string
+ */
+ protected static function encode6Bits(int $src) : string
+ {
+ $src += 0x2e;
+ // if ($src > 0x39) $src += 0x41 - 0x3a; // 7
+ $src += 0x39 - $src >> 8 & 7;
+ // if ($src > 0x5a) $src += 0x61 - 0x5b; // 6
+ $src += 0x5a - $src >> 8 & 6;
+ return pack('C', $src);
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/paragonie/constant_time_encoding/src/Base64UrlSafe.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/paragonie/constant_time_encoding/src/Base64UrlSafe.php
new file mode 100755
index 00000000..5ba9ab8b
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/paragonie/constant_time_encoding/src/Base64UrlSafe.php
@@ -0,0 +1,83 @@
+ 0x40 && $src < 0x5b) $ret += $src - 0x41 + 1; // -64
+ $ret += (0x40 - $src & $src - 0x5b) >> 8 & $src - 64;
+ // if ($src > 0x60 && $src < 0x7b) $ret += $src - 0x61 + 26 + 1; // -70
+ $ret += (0x60 - $src & $src - 0x7b) >> 8 & $src - 70;
+ // if ($src > 0x2f && $src < 0x3a) $ret += $src - 0x30 + 52 + 1; // 5
+ $ret += (0x2f - $src & $src - 0x3a) >> 8 & $src + 5;
+ // if ($src == 0x2c) $ret += 62 + 1;
+ $ret += (0x2c - $src & $src - 0x2e) >> 8 & 63;
+ // if ($src == 0x5f) ret += 63 + 1;
+ $ret += (0x5e - $src & $src - 0x60) >> 8 & 64;
+ return $ret;
+ }
+ /**
+ * Uses bitwise operators instead of table-lookups to turn 8-bit integers
+ * into 6-bit integers.
+ *
+ * @param int $src
+ * @return string
+ */
+ protected static function encode6Bits(int $src) : string
+ {
+ $diff = 0x41;
+ // if ($src > 25) $diff += 0x61 - 0x41 - 26; // 6
+ $diff += 25 - $src >> 8 & 6;
+ // if ($src > 51) $diff += 0x30 - 0x61 - 26; // -75
+ $diff -= 51 - $src >> 8 & 75;
+ // if ($src > 61) $diff += 0x2d - 0x30 - 10; // -13
+ $diff -= 61 - $src >> 8 & 13;
+ // if ($src > 62) $diff += 0x5f - 0x2b - 1; // 3
+ $diff += 62 - $src >> 8 & 49;
+ return pack('C', $src + $diff);
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/paragonie/constant_time_encoding/src/Binary.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/paragonie/constant_time_encoding/src/Binary.php
new file mode 100755
index 00000000..40af6766
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/paragonie/constant_time_encoding/src/Binary.php
@@ -0,0 +1,98 @@
+getMessage(), $ex->getCode(), $ex);
+ }
+ }
+ $hex = '';
+ $len = Binary::safeStrlen($binString);
+ for ($i = 0; $i < $len; ++$i) {
+ /** @var array $chunk */
+ $chunk = unpack('C', $binString[$i]);
+ $c = $chunk[1] & 0xf;
+ $b = $chunk[1] >> 4;
+ $hex .= pack('CC', 87 + $b + ($b - 10 >> 8 & ~38), 87 + $c + ($c - 10 >> 8 & ~38));
+ }
+ return $hex;
+ }
+ /**
+ * Convert a binary string into a hexadecimal string without cache-timing
+ * leaks, returning uppercase letters (as per RFC 4648)
+ *
+ * @param string $binString (raw binary)
+ * @return string
+ * @throws TypeError
+ */
+ public static function encodeUpper(
+ #[SensitiveParameter]
+ string $binString
+ ) : string
+ {
+ $hex = '';
+ $len = Binary::safeStrlen($binString);
+ for ($i = 0; $i < $len; ++$i) {
+ /** @var array $chunk */
+ $chunk = unpack('C', $binString[$i]);
+ $c = $chunk[1] & 0xf;
+ $b = $chunk[1] >> 4;
+ $hex .= pack('CC', 55 + $b + ($b - 10 >> 8 & ~6), 55 + $c + ($c - 10 >> 8 & ~6));
+ }
+ return $hex;
+ }
+ /**
+ * Convert a hexadecimal string into a binary string without cache-timing
+ * leaks
+ *
+ * @param string $encodedString
+ * @param bool $strictPadding
+ * @return string (raw binary)
+ * @throws RangeException
+ */
+ public static function decode(
+ #[SensitiveParameter]
+ string $encodedString,
+ bool $strictPadding = \false
+ ) : string
+ {
+ if (extension_loaded('sodium') && $strictPadding) {
+ try {
+ return sodium_hex2bin($encodedString);
+ } catch (SodiumException $ex) {
+ throw new RangeException($ex->getMessage(), $ex->getCode(), $ex);
+ }
+ }
+ $hex_pos = 0;
+ $bin = '';
+ $c_acc = 0;
+ $hex_len = Binary::safeStrlen($encodedString);
+ $state = 0;
+ if (($hex_len & 1) !== 0) {
+ if ($strictPadding) {
+ throw new RangeException('Expected an even number of hexadecimal characters');
+ } else {
+ $encodedString = '0' . $encodedString;
+ ++$hex_len;
+ }
+ }
+ /** @var array $chunk */
+ $chunk = unpack('C*', $encodedString);
+ while ($hex_pos < $hex_len) {
+ ++$hex_pos;
+ $c = $chunk[$hex_pos];
+ $c_num = $c ^ 48;
+ $c_num0 = $c_num - 10 >> 8;
+ $c_alpha = ($c & ~32) - 55;
+ $c_alpha0 = ($c_alpha - 10 ^ $c_alpha - 16) >> 8;
+ if (($c_num0 | $c_alpha0) === 0) {
+ throw new RangeException('Expected hexadecimal character');
+ }
+ $c_val = $c_num0 & $c_num | $c_alpha & $c_alpha0;
+ if ($state === 0) {
+ $c_acc = $c_val * 16;
+ } else {
+ $bin .= pack('C', $c_acc | $c_val);
+ }
+ $state ^= 1;
+ }
+ return $bin;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/paragonie/constant_time_encoding/src/RFC4648.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/paragonie/constant_time_encoding/src/RFC4648.php
new file mode 100755
index 00000000..63594502
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/paragonie/constant_time_encoding/src/RFC4648.php
@@ -0,0 +1,206 @@
+ "Zm9v"
+ *
+ * @param string $str
+ * @return string
+ *
+ * @throws TypeError
+ */
+ public static function base64Encode(
+ #[\SensitiveParameter]
+ string $str
+ ) : string
+ {
+ return Base64::encode($str);
+ }
+ /**
+ * RFC 4648 Base64 decoding
+ *
+ * "Zm9v" -> "foo"
+ *
+ * @param string $str
+ * @return string
+ *
+ * @throws TypeError
+ */
+ public static function base64Decode(
+ #[\SensitiveParameter]
+ string $str
+ ) : string
+ {
+ return Base64::decode($str, \true);
+ }
+ /**
+ * RFC 4648 Base64 (URL Safe) encoding
+ *
+ * "foo" -> "Zm9v"
+ *
+ * @param string $str
+ * @return string
+ *
+ * @throws TypeError
+ */
+ public static function base64UrlSafeEncode(
+ #[\SensitiveParameter]
+ string $str
+ ) : string
+ {
+ return Base64UrlSafe::encode($str);
+ }
+ /**
+ * RFC 4648 Base64 (URL Safe) decoding
+ *
+ * "Zm9v" -> "foo"
+ *
+ * @param string $str
+ * @return string
+ *
+ * @throws TypeError
+ */
+ public static function base64UrlSafeDecode(
+ #[\SensitiveParameter]
+ string $str
+ ) : string
+ {
+ return Base64UrlSafe::decode($str, \true);
+ }
+ /**
+ * RFC 4648 Base32 encoding
+ *
+ * "foo" -> "MZXW6==="
+ *
+ * @param string $str
+ * @return string
+ *
+ * @throws TypeError
+ */
+ public static function base32Encode(
+ #[\SensitiveParameter]
+ string $str
+ ) : string
+ {
+ return Base32::encodeUpper($str);
+ }
+ /**
+ * RFC 4648 Base32 encoding
+ *
+ * "MZXW6===" -> "foo"
+ *
+ * @param string $str
+ * @return string
+ *
+ * @throws TypeError
+ */
+ public static function base32Decode(
+ #[\SensitiveParameter]
+ string $str
+ ) : string
+ {
+ return Base32::decodeUpper($str, \true);
+ }
+ /**
+ * RFC 4648 Base32-Hex encoding
+ *
+ * "foo" -> "CPNMU==="
+ *
+ * @param string $str
+ * @return string
+ *
+ * @throws TypeError
+ */
+ public static function base32HexEncode(
+ #[\SensitiveParameter]
+ string $str
+ ) : string
+ {
+ return Base32::encodeUpper($str);
+ }
+ /**
+ * RFC 4648 Base32-Hex decoding
+ *
+ * "CPNMU===" -> "foo"
+ *
+ * @param string $str
+ * @return string
+ *
+ * @throws TypeError
+ */
+ public static function base32HexDecode(
+ #[\SensitiveParameter]
+ string $str
+ ) : string
+ {
+ return Base32::decodeUpper($str, \true);
+ }
+ /**
+ * RFC 4648 Base16 decoding
+ *
+ * "foo" -> "666F6F"
+ *
+ * @param string $str
+ * @return string
+ *
+ * @throws TypeError
+ */
+ public static function base16Encode(
+ #[\SensitiveParameter]
+ string $str
+ ) : string
+ {
+ return Hex::encodeUpper($str);
+ }
+ /**
+ * RFC 4648 Base16 decoding
+ *
+ * "666F6F" -> "foo"
+ *
+ * @param string $str
+ * @return string
+ */
+ public static function base16Decode(
+ #[\SensitiveParameter]
+ string $str
+ ) : string
+ {
+ return Hex::decode($str, \true);
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/psr/cache/src/CacheException.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/psr/cache/src/CacheException.php
new file mode 100755
index 00000000..c239c155
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/psr/cache/src/CacheException.php
@@ -0,0 +1,10 @@
+getHeaders() as $name => $values) {
+ * echo $name . ": " . implode(", ", $values);
+ * }
+ *
+ * // Emit headers iteratively:
+ * foreach ($message->getHeaders() as $name => $values) {
+ * foreach ($values as $value) {
+ * header(sprintf('%s: %s', $name, $value), false);
+ * }
+ * }
+ *
+ * While header names are not case-sensitive, getHeaders() will preserve the
+ * exact case in which headers were originally specified.
+ *
+ * @return string[][] Returns an associative array of the message's headers. Each
+ * key MUST be a header name, and each value MUST be an array of strings
+ * for that header.
+ */
+ public function getHeaders() : array;
+ /**
+ * Checks if a header exists by the given case-insensitive name.
+ *
+ * @param string $name Case-insensitive header field name.
+ * @return bool Returns true if any header names match the given header
+ * name using a case-insensitive string comparison. Returns false if
+ * no matching header name is found in the message.
+ */
+ public function hasHeader(string $name) : bool;
+ /**
+ * Retrieves a message header value by the given case-insensitive name.
+ *
+ * This method returns an array of all the header values of the given
+ * case-insensitive header name.
+ *
+ * If the header does not appear in the message, this method MUST return an
+ * empty array.
+ *
+ * @param string $name Case-insensitive header field name.
+ * @return string[] An array of string values as provided for the given
+ * header. If the header does not appear in the message, this method MUST
+ * return an empty array.
+ */
+ public function getHeader(string $name) : array;
+ /**
+ * Retrieves a comma-separated string of the values for a single header.
+ *
+ * This method returns all of the header values of the given
+ * case-insensitive header name as a string concatenated together using
+ * a comma.
+ *
+ * NOTE: Not all header values may be appropriately represented using
+ * comma concatenation. For such headers, use getHeader() instead
+ * and supply your own delimiter when concatenating.
+ *
+ * If the header does not appear in the message, this method MUST return
+ * an empty string.
+ *
+ * @param string $name Case-insensitive header field name.
+ * @return string A string of values as provided for the given header
+ * concatenated together using a comma. If the header does not appear in
+ * the message, this method MUST return an empty string.
+ */
+ public function getHeaderLine(string $name) : string;
+ /**
+ * Return an instance with the provided value replacing the specified header.
+ *
+ * While header names are case-insensitive, the casing of the header will
+ * be preserved by this function, and returned from getHeaders().
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return an instance that has the
+ * new and/or updated header and value.
+ *
+ * @param string $name Case-insensitive header field name.
+ * @param string|string[] $value Header value(s).
+ * @return static
+ * @throws \InvalidArgumentException for invalid header names or values.
+ */
+ public function withHeader(string $name, $value) : MessageInterface;
+ /**
+ * Return an instance with the specified header appended with the given value.
+ *
+ * Existing values for the specified header will be maintained. The new
+ * value(s) will be appended to the existing list. If the header did not
+ * exist previously, it will be added.
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return an instance that has the
+ * new header and/or value.
+ *
+ * @param string $name Case-insensitive header field name to add.
+ * @param string|string[] $value Header value(s).
+ * @return static
+ * @throws \InvalidArgumentException for invalid header names or values.
+ */
+ public function withAddedHeader(string $name, $value) : MessageInterface;
+ /**
+ * Return an instance without the specified header.
+ *
+ * Header resolution MUST be done without case-sensitivity.
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return an instance that removes
+ * the named header.
+ *
+ * @param string $name Case-insensitive header field name to remove.
+ * @return static
+ */
+ public function withoutHeader(string $name) : MessageInterface;
+ /**
+ * Gets the body of the message.
+ *
+ * @return StreamInterface Returns the body as a stream.
+ */
+ public function getBody() : StreamInterface;
+ /**
+ * Return an instance with the specified message body.
+ *
+ * The body MUST be a StreamInterface object.
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return a new instance that has the
+ * new body stream.
+ *
+ * @param StreamInterface $body Body.
+ * @return static
+ * @throws \InvalidArgumentException When the body is not valid.
+ */
+ public function withBody(StreamInterface $body) : MessageInterface;
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/psr/http-message/src/RequestInterface.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/psr/http-message/src/RequestInterface.php
new file mode 100755
index 00000000..becc9d32
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/psr/http-message/src/RequestInterface.php
@@ -0,0 +1,124 @@
+getQuery()`
+ * or from the `QUERY_STRING` server param.
+ *
+ * @return array
+ */
+ public function getQueryParams() : array;
+ /**
+ * Return an instance with the specified query string arguments.
+ *
+ * These values SHOULD remain immutable over the course of the incoming
+ * request. They MAY be injected during instantiation, such as from PHP's
+ * $_GET superglobal, or MAY be derived from some other value such as the
+ * URI. In cases where the arguments are parsed from the URI, the data
+ * MUST be compatible with what PHP's parse_str() would return for
+ * purposes of how duplicate query parameters are handled, and how nested
+ * sets are handled.
+ *
+ * Setting query string arguments MUST NOT change the URI stored by the
+ * request, nor the values in the server params.
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return an instance that has the
+ * updated query string arguments.
+ *
+ * @param array $query Array of query string arguments, typically from
+ * $_GET.
+ * @return static
+ */
+ public function withQueryParams(array $query) : ServerRequestInterface;
+ /**
+ * Retrieve normalized file upload data.
+ *
+ * This method returns upload metadata in a normalized tree, with each leaf
+ * an instance of Psr\Http\Message\UploadedFileInterface.
+ *
+ * These values MAY be prepared from $_FILES or the message body during
+ * instantiation, or MAY be injected via withUploadedFiles().
+ *
+ * @return array An array tree of UploadedFileInterface instances; an empty
+ * array MUST be returned if no data is present.
+ */
+ public function getUploadedFiles() : array;
+ /**
+ * Create a new instance with the specified uploaded files.
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return an instance that has the
+ * updated body parameters.
+ *
+ * @param array $uploadedFiles An array tree of UploadedFileInterface instances.
+ * @return static
+ * @throws \InvalidArgumentException if an invalid structure is provided.
+ */
+ public function withUploadedFiles(array $uploadedFiles) : ServerRequestInterface;
+ /**
+ * Retrieve any parameters provided in the request body.
+ *
+ * If the request Content-Type is either application/x-www-form-urlencoded
+ * or multipart/form-data, and the request method is POST, this method MUST
+ * return the contents of $_POST.
+ *
+ * Otherwise, this method may return any results of deserializing
+ * the request body content; as parsing returns structured content, the
+ * potential types MUST be arrays or objects only. A null value indicates
+ * the absence of body content.
+ *
+ * @return null|array|object The deserialized body parameters, if any.
+ * These will typically be an array or object.
+ */
+ public function getParsedBody();
+ /**
+ * Return an instance with the specified body parameters.
+ *
+ * These MAY be injected during instantiation.
+ *
+ * If the request Content-Type is either application/x-www-form-urlencoded
+ * or multipart/form-data, and the request method is POST, use this method
+ * ONLY to inject the contents of $_POST.
+ *
+ * The data IS NOT REQUIRED to come from $_POST, but MUST be the results of
+ * deserializing the request body content. Deserialization/parsing returns
+ * structured data, and, as such, this method ONLY accepts arrays or objects,
+ * or a null value if nothing was available to parse.
+ *
+ * As an example, if content negotiation determines that the request data
+ * is a JSON payload, this method could be used to create a request
+ * instance with the deserialized parameters.
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return an instance that has the
+ * updated body parameters.
+ *
+ * @param null|array|object $data The deserialized body data. This will
+ * typically be in an array or object.
+ * @return static
+ * @throws \InvalidArgumentException if an unsupported argument type is
+ * provided.
+ */
+ public function withParsedBody($data) : ServerRequestInterface;
+ /**
+ * Retrieve attributes derived from the request.
+ *
+ * The request "attributes" may be used to allow injection of any
+ * parameters derived from the request: e.g., the results of path
+ * match operations; the results of decrypting cookies; the results of
+ * deserializing non-form-encoded message bodies; etc. Attributes
+ * will be application and request specific, and CAN be mutable.
+ *
+ * @return array Attributes derived from the request.
+ */
+ public function getAttributes() : array;
+ /**
+ * Retrieve a single derived request attribute.
+ *
+ * Retrieves a single derived request attribute as described in
+ * getAttributes(). If the attribute has not been previously set, returns
+ * the default value as provided.
+ *
+ * This method obviates the need for a hasAttribute() method, as it allows
+ * specifying a default value to return if the attribute is not found.
+ *
+ * @see getAttributes()
+ * @param string $name The attribute name.
+ * @param mixed $default Default value to return if the attribute does not exist.
+ * @return mixed
+ */
+ public function getAttribute(string $name, $default = null);
+ /**
+ * Return an instance with the specified derived request attribute.
+ *
+ * This method allows setting a single derived request attribute as
+ * described in getAttributes().
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return an instance that has the
+ * updated attribute.
+ *
+ * @see getAttributes()
+ * @param string $name The attribute name.
+ * @param mixed $value The value of the attribute.
+ * @return static
+ */
+ public function withAttribute(string $name, $value) : ServerRequestInterface;
+ /**
+ * Return an instance that removes the specified derived request attribute.
+ *
+ * This method allows removing a single derived request attribute as
+ * described in getAttributes().
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return an instance that removes
+ * the attribute.
+ *
+ * @see getAttributes()
+ * @param string $name The attribute name.
+ * @return static
+ */
+ public function withoutAttribute(string $name) : ServerRequestInterface;
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/psr/http-message/src/StreamInterface.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/psr/http-message/src/StreamInterface.php
new file mode 100755
index 00000000..13c0b1ab
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/psr/http-message/src/StreamInterface.php
@@ -0,0 +1,144 @@
+
+ * [user-info@]host[:port]
+ *
+ *
+ * If the port component is not set or is the standard port for the current
+ * scheme, it SHOULD NOT be included.
+ *
+ * @see https://tools.ietf.org/html/rfc3986#section-3.2
+ * @return string The URI authority, in "[user-info@]host[:port]" format.
+ */
+ public function getAuthority() : string;
+ /**
+ * Retrieve the user information component of the URI.
+ *
+ * If no user information is present, this method MUST return an empty
+ * string.
+ *
+ * If a user is present in the URI, this will return that value;
+ * additionally, if the password is also present, it will be appended to the
+ * user value, with a colon (":") separating the values.
+ *
+ * The trailing "@" character is not part of the user information and MUST
+ * NOT be added.
+ *
+ * @return string The URI user information, in "username[:password]" format.
+ */
+ public function getUserInfo() : string;
+ /**
+ * Retrieve the host component of the URI.
+ *
+ * If no host is present, this method MUST return an empty string.
+ *
+ * The value returned MUST be normalized to lowercase, per RFC 3986
+ * Section 3.2.2.
+ *
+ * @see http://tools.ietf.org/html/rfc3986#section-3.2.2
+ * @return string The URI host.
+ */
+ public function getHost() : string;
+ /**
+ * Retrieve the port component of the URI.
+ *
+ * If a port is present, and it is non-standard for the current scheme,
+ * this method MUST return it as an integer. If the port is the standard port
+ * used with the current scheme, this method SHOULD return null.
+ *
+ * If no port is present, and no scheme is present, this method MUST return
+ * a null value.
+ *
+ * If no port is present, but a scheme is present, this method MAY return
+ * the standard port for that scheme, but SHOULD return null.
+ *
+ * @return null|int The URI port.
+ */
+ public function getPort() : ?int;
+ /**
+ * Retrieve the path component of the URI.
+ *
+ * The path can either be empty or absolute (starting with a slash) or
+ * rootless (not starting with a slash). Implementations MUST support all
+ * three syntaxes.
+ *
+ * Normally, the empty path "" and absolute path "/" are considered equal as
+ * defined in RFC 7230 Section 2.7.3. But this method MUST NOT automatically
+ * do this normalization because in contexts with a trimmed base path, e.g.
+ * the front controller, this difference becomes significant. It's the task
+ * of the user to handle both "" and "/".
+ *
+ * The value returned MUST be percent-encoded, but MUST NOT double-encode
+ * any characters. To determine what characters to encode, please refer to
+ * RFC 3986, Sections 2 and 3.3.
+ *
+ * As an example, if the value should include a slash ("/") not intended as
+ * delimiter between path segments, that value MUST be passed in encoded
+ * form (e.g., "%2F") to the instance.
+ *
+ * @see https://tools.ietf.org/html/rfc3986#section-2
+ * @see https://tools.ietf.org/html/rfc3986#section-3.3
+ * @return string The URI path.
+ */
+ public function getPath() : string;
+ /**
+ * Retrieve the query string of the URI.
+ *
+ * If no query string is present, this method MUST return an empty string.
+ *
+ * The leading "?" character is not part of the query and MUST NOT be
+ * added.
+ *
+ * The value returned MUST be percent-encoded, but MUST NOT double-encode
+ * any characters. To determine what characters to encode, please refer to
+ * RFC 3986, Sections 2 and 3.4.
+ *
+ * As an example, if a value in a key/value pair of the query string should
+ * include an ampersand ("&") not intended as a delimiter between values,
+ * that value MUST be passed in encoded form (e.g., "%26") to the instance.
+ *
+ * @see https://tools.ietf.org/html/rfc3986#section-2
+ * @see https://tools.ietf.org/html/rfc3986#section-3.4
+ * @return string The URI query string.
+ */
+ public function getQuery() : string;
+ /**
+ * Retrieve the fragment component of the URI.
+ *
+ * If no fragment is present, this method MUST return an empty string.
+ *
+ * The leading "#" character is not part of the fragment and MUST NOT be
+ * added.
+ *
+ * The value returned MUST be percent-encoded, but MUST NOT double-encode
+ * any characters. To determine what characters to encode, please refer to
+ * RFC 3986, Sections 2 and 3.5.
+ *
+ * @see https://tools.ietf.org/html/rfc3986#section-2
+ * @see https://tools.ietf.org/html/rfc3986#section-3.5
+ * @return string The URI fragment.
+ */
+ public function getFragment() : string;
+ /**
+ * Return an instance with the specified scheme.
+ *
+ * This method MUST retain the state of the current instance, and return
+ * an instance that contains the specified scheme.
+ *
+ * Implementations MUST support the schemes "http" and "https" case
+ * insensitively, and MAY accommodate other schemes if required.
+ *
+ * An empty scheme is equivalent to removing the scheme.
+ *
+ * @param string $scheme The scheme to use with the new instance.
+ * @return static A new instance with the specified scheme.
+ * @throws \InvalidArgumentException for invalid or unsupported schemes.
+ */
+ public function withScheme(string $scheme) : UriInterface;
+ /**
+ * Return an instance with the specified user information.
+ *
+ * This method MUST retain the state of the current instance, and return
+ * an instance that contains the specified user information.
+ *
+ * Password is optional, but the user information MUST include the
+ * user; an empty string for the user is equivalent to removing user
+ * information.
+ *
+ * @param string $user The user name to use for authority.
+ * @param null|string $password The password associated with $user.
+ * @return static A new instance with the specified user information.
+ */
+ public function withUserInfo(string $user, ?string $password = null) : UriInterface;
+ /**
+ * Return an instance with the specified host.
+ *
+ * This method MUST retain the state of the current instance, and return
+ * an instance that contains the specified host.
+ *
+ * An empty host value is equivalent to removing the host.
+ *
+ * @param string $host The hostname to use with the new instance.
+ * @return static A new instance with the specified host.
+ * @throws \InvalidArgumentException for invalid hostnames.
+ */
+ public function withHost(string $host) : UriInterface;
+ /**
+ * Return an instance with the specified port.
+ *
+ * This method MUST retain the state of the current instance, and return
+ * an instance that contains the specified port.
+ *
+ * Implementations MUST raise an exception for ports outside the
+ * established TCP and UDP port ranges.
+ *
+ * A null value provided for the port is equivalent to removing the port
+ * information.
+ *
+ * @param null|int $port The port to use with the new instance; a null value
+ * removes the port information.
+ * @return static A new instance with the specified port.
+ * @throws \InvalidArgumentException for invalid ports.
+ */
+ public function withPort(?int $port) : UriInterface;
+ /**
+ * Return an instance with the specified path.
+ *
+ * This method MUST retain the state of the current instance, and return
+ * an instance that contains the specified path.
+ *
+ * The path can either be empty or absolute (starting with a slash) or
+ * rootless (not starting with a slash). Implementations MUST support all
+ * three syntaxes.
+ *
+ * If the path is intended to be domain-relative rather than path relative then
+ * it must begin with a slash ("/"). Paths not starting with a slash ("/")
+ * are assumed to be relative to some base path known to the application or
+ * consumer.
+ *
+ * Users can provide both encoded and decoded path characters.
+ * Implementations ensure the correct encoding as outlined in getPath().
+ *
+ * @param string $path The path to use with the new instance.
+ * @return static A new instance with the specified path.
+ * @throws \InvalidArgumentException for invalid paths.
+ */
+ public function withPath(string $path) : UriInterface;
+ /**
+ * Return an instance with the specified query string.
+ *
+ * This method MUST retain the state of the current instance, and return
+ * an instance that contains the specified query string.
+ *
+ * Users can provide both encoded and decoded query characters.
+ * Implementations ensure the correct encoding as outlined in getQuery().
+ *
+ * An empty query string value is equivalent to removing the query string.
+ *
+ * @param string $query The query string to use with the new instance.
+ * @return static A new instance with the specified query string.
+ * @throws \InvalidArgumentException for invalid query strings.
+ */
+ public function withQuery(string $query) : UriInterface;
+ /**
+ * Return an instance with the specified URI fragment.
+ *
+ * This method MUST retain the state of the current instance, and return
+ * an instance that contains the specified URI fragment.
+ *
+ * Users can provide both encoded and decoded fragment characters.
+ * Implementations ensure the correct encoding as outlined in getFragment().
+ *
+ * An empty fragment value is equivalent to removing the fragment.
+ *
+ * @param string $fragment The fragment to use with the new instance.
+ * @return static A new instance with the specified fragment.
+ */
+ public function withFragment(string $fragment) : UriInterface;
+ /**
+ * Return the string representation as a URI reference.
+ *
+ * Depending on which components of the URI are present, the resulting
+ * string is either a full URI or relative reference according to RFC 3986,
+ * Section 4.1. The method concatenates the various components of the URI,
+ * using the appropriate delimiters:
+ *
+ * - If a scheme is present, it MUST be suffixed by ":".
+ * - If an authority is present, it MUST be prefixed by "//".
+ * - The path can be concatenated without delimiters. But there are two
+ * cases where the path has to be adjusted to make the URI reference
+ * valid as PHP does not allow to throw an exception in __toString():
+ * - If the path is rootless and an authority is present, the path MUST
+ * be prefixed by "/".
+ * - If the path is starting with more than one "/" and no authority is
+ * present, the starting slashes MUST be reduced to one.
+ * - If a query is present, it MUST be prefixed by "?".
+ * - If a fragment is present, it MUST be prefixed by "#".
+ *
+ * @see http://tools.ietf.org/html/rfc3986#section-4.1
+ * @return string
+ */
+ public function __toString() : string;
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/psr/log/LICENSE b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/psr/log/LICENSE
new file mode 100755
index 00000000..474c952b
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/psr/log/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2012 PHP Framework Interoperability Group
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/psr/log/Psr/Log/AbstractLogger.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/psr/log/Psr/Log/AbstractLogger.php
new file mode 100755
index 00000000..5646536e
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/psr/log/Psr/Log/AbstractLogger.php
@@ -0,0 +1,121 @@
+log(LogLevel::EMERGENCY, $message, $context);
+ }
+ /**
+ * Action must be taken immediately.
+ *
+ * Example: Entire website down, database unavailable, etc. This should
+ * trigger the SMS alerts and wake you up.
+ *
+ * @param string $message
+ * @param mixed[] $context
+ *
+ * @return void
+ */
+ public function alert($message, array $context = array())
+ {
+ $this->log(LogLevel::ALERT, $message, $context);
+ }
+ /**
+ * Critical conditions.
+ *
+ * Example: Application component unavailable, unexpected exception.
+ *
+ * @param string $message
+ * @param mixed[] $context
+ *
+ * @return void
+ */
+ public function critical($message, array $context = array())
+ {
+ $this->log(LogLevel::CRITICAL, $message, $context);
+ }
+ /**
+ * Runtime errors that do not require immediate action but should typically
+ * be logged and monitored.
+ *
+ * @param string $message
+ * @param mixed[] $context
+ *
+ * @return void
+ */
+ public function error($message, array $context = array())
+ {
+ $this->log(LogLevel::ERROR, $message, $context);
+ }
+ /**
+ * Exceptional occurrences that are not errors.
+ *
+ * Example: Use of deprecated APIs, poor use of an API, undesirable things
+ * that are not necessarily wrong.
+ *
+ * @param string $message
+ * @param mixed[] $context
+ *
+ * @return void
+ */
+ public function warning($message, array $context = array())
+ {
+ $this->log(LogLevel::WARNING, $message, $context);
+ }
+ /**
+ * Normal but significant events.
+ *
+ * @param string $message
+ * @param mixed[] $context
+ *
+ * @return void
+ */
+ public function notice($message, array $context = array())
+ {
+ $this->log(LogLevel::NOTICE, $message, $context);
+ }
+ /**
+ * Interesting events.
+ *
+ * Example: User logs in, SQL logs.
+ *
+ * @param string $message
+ * @param mixed[] $context
+ *
+ * @return void
+ */
+ public function info($message, array $context = array())
+ {
+ $this->log(LogLevel::INFO, $message, $context);
+ }
+ /**
+ * Detailed debug information.
+ *
+ * @param string $message
+ * @param mixed[] $context
+ *
+ * @return void
+ */
+ public function debug($message, array $context = array())
+ {
+ $this->log(LogLevel::DEBUG, $message, $context);
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/psr/log/Psr/Log/InvalidArgumentException.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/psr/log/Psr/Log/InvalidArgumentException.php
new file mode 100755
index 00000000..0ccd7a5a
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/psr/log/Psr/Log/InvalidArgumentException.php
@@ -0,0 +1,7 @@
+logger = $logger;
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/psr/log/Psr/Log/LoggerInterface.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/psr/log/Psr/Log/LoggerInterface.php
new file mode 100755
index 00000000..0baeaa71
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/psr/log/Psr/Log/LoggerInterface.php
@@ -0,0 +1,117 @@
+log(LogLevel::EMERGENCY, $message, $context);
+ }
+ /**
+ * Action must be taken immediately.
+ *
+ * Example: Entire website down, database unavailable, etc. This should
+ * trigger the SMS alerts and wake you up.
+ *
+ * @param string $message
+ * @param array $context
+ *
+ * @return void
+ */
+ public function alert($message, array $context = array())
+ {
+ $this->log(LogLevel::ALERT, $message, $context);
+ }
+ /**
+ * Critical conditions.
+ *
+ * Example: Application component unavailable, unexpected exception.
+ *
+ * @param string $message
+ * @param array $context
+ *
+ * @return void
+ */
+ public function critical($message, array $context = array())
+ {
+ $this->log(LogLevel::CRITICAL, $message, $context);
+ }
+ /**
+ * Runtime errors that do not require immediate action but should typically
+ * be logged and monitored.
+ *
+ * @param string $message
+ * @param array $context
+ *
+ * @return void
+ */
+ public function error($message, array $context = array())
+ {
+ $this->log(LogLevel::ERROR, $message, $context);
+ }
+ /**
+ * Exceptional occurrences that are not errors.
+ *
+ * Example: Use of deprecated APIs, poor use of an API, undesirable things
+ * that are not necessarily wrong.
+ *
+ * @param string $message
+ * @param array $context
+ *
+ * @return void
+ */
+ public function warning($message, array $context = array())
+ {
+ $this->log(LogLevel::WARNING, $message, $context);
+ }
+ /**
+ * Normal but significant events.
+ *
+ * @param string $message
+ * @param array $context
+ *
+ * @return void
+ */
+ public function notice($message, array $context = array())
+ {
+ $this->log(LogLevel::NOTICE, $message, $context);
+ }
+ /**
+ * Interesting events.
+ *
+ * Example: User logs in, SQL logs.
+ *
+ * @param string $message
+ * @param array $context
+ *
+ * @return void
+ */
+ public function info($message, array $context = array())
+ {
+ $this->log(LogLevel::INFO, $message, $context);
+ }
+ /**
+ * Detailed debug information.
+ *
+ * @param string $message
+ * @param array $context
+ *
+ * @return void
+ */
+ public function debug($message, array $context = array())
+ {
+ $this->log(LogLevel::DEBUG, $message, $context);
+ }
+ /**
+ * Logs with an arbitrary level.
+ *
+ * @param mixed $level
+ * @param string $message
+ * @param array $context
+ *
+ * @return void
+ *
+ * @throws \Psr\Log\InvalidArgumentException
+ */
+ public abstract function log($level, $message, array $context = array());
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/psr/log/Psr/Log/NullLogger.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/psr/log/Psr/Log/NullLogger.php
new file mode 100755
index 00000000..f5416cc3
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/psr/log/Psr/Log/NullLogger.php
@@ -0,0 +1,30 @@
+logger) { }`
+ * blocks.
+ */
+class NullLogger extends AbstractLogger
+{
+ /**
+ * Logs with an arbitrary level.
+ *
+ * @param mixed $level
+ * @param string $message
+ * @param array $context
+ *
+ * @return void
+ *
+ * @throws \Psr\Log\InvalidArgumentException
+ */
+ public function log($level, $message, array $context = array())
+ {
+ // noop
+ }
+}
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/symfony/deprecation-contracts/LICENSE b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/symfony/deprecation-contracts/LICENSE
new file mode 100755
index 00000000..0ed3a246
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/symfony/deprecation-contracts/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2020-present Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/wp-content/plugins/wp-mail-smtp/vendor_prefixed/symfony/deprecation-contracts/function.php b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/symfony/deprecation-contracts/function.php
new file mode 100755
index 00000000..d4371504
--- /dev/null
+++ b/wp-content/plugins/wp-mail-smtp/vendor_prefixed/symfony/deprecation-contracts/function.php
@@ -0,0 +1,27 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+if (!function_exists('trigger_deprecation')) {
+ /**
+ * Triggers a silenced deprecation notice.
+ *
+ * @param string $package The name of the Composer package that is triggering the deprecation
+ * @param string $version The version of the package that introduced the deprecation
+ * @param string $message The message of the deprecation
+ * @param mixed ...$args Values to insert in the message using printf() formatting
+ *
+ * @author Nicolas Grekas
' . esc_html__( 'Please deactivate the free version of the WP Mail SMTP plugin before activating WP Mail SMTP Pro.', 'wp-mail-smtp' ) . '
';
+
+ if ( isset( $_GET['activate'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+ unset( $_GET['activate'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+ }
+ }
+ }
+
+ // Stop the plugin loading.
+ if ( wp_mail_smtp_check_pro_loading_allowed() === true ) {
+ return;
+ }
+}
+
+if ( ! function_exists( 'wp_mail_smtp_insecure_php_version_notice' ) ) {
+ /**
+ * Display admin notice, if the server is using old/insecure PHP version.
+ *
+ * @since 2.0.0
+ */
+ function wp_mail_smtp_insecure_php_version_notice() {
+
+ ?>
+
+
+ insecure version of PHP that is no longer supported. Please contact your web hosting provider to update your PHP version or switch to a recommended WordPress hosting company.', 'wp-mail-smtp' ),
+ array(
+ 'a' => array(
+ 'href' => array(),
+ 'target' => array(),
+ 'rel' => array(),
+ ),
+ 'strong' => array(),
+ )
+ ),
+ 'https://www.wpbeginner.com/wordpress-hosting/'
+ );
+ ?>
+
+ 'WordPress',
+ 'utm_medium' => 'Admin Notice',
+ 'utm_campaign' => is_readable( rtrim( plugin_dir_path( __FILE__ ), '/\\' ) . '/src/Pro/Pro.php' ) ? 'plugin' : 'liteplugin',
+ 'utm_content' => 'Minimal Required PHP Version',
+ ],
+ 'https://wpmailsmtp.com/docs/supported-php-versions-for-wp-mail-smtp/'
+ );
+
+ printf(
+ wp_kses( /* translators: %s - WPMailSMTP.com docs URL with more details. */
+ __( 'WP Mail SMTP plugin is disabled on your site until you fix the issue. Read more for additional information.', 'wp-mail-smtp' ),
+ array(
+ 'a' => array(
+ 'href' => array(),
+ 'target' => array(),
+ 'rel' => array(),
+ ),
+ 'strong' => array(),
+ )
+ ),
+ esc_url( $doc_link )
+ );
+ ?>
+
+
+
+
+
+
+ old version of WordPress that is no longer supported by WP Mail SMTP. Please update your WordPress site to at least version %s.', 'wp-mail-smtp' ),
+ [
+ 'strong' => [],
+ ]
+ ),
+ esc_html( WPMS_WP_VER )
+ );
+ ?>
+
+ WP Mail SMTP plugin is disabled on your site until WordPress is updated to the required version.', 'wp-mail-smtp' ),
+ [
+ 'strong' => [],
+ ]
+ );
+ ?>
+