From b9651b4aedece064720576e98f04b5064af92726 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 27 Mar 2026 19:49:21 +0000 Subject: [PATCH 1/2] Initial plan From 6e9053f9954a8ea66f5558b716c5307f29644754 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 27 Mar 2026 19:59:18 +0000 Subject: [PATCH 2/2] Security fixes for PR #1295: authorization bypass, unconstrained plugin install, XSS Agent-Logs-Url: https://github.com/Codeinwp/visualizer/sessions/0ea8792d-4154-4e13-989d-301380d262b1 Co-authored-by: selul <3330746+selul@users.noreply.github.com> --- SECURITY_REPORT.md | 139 ++++++++ classes/Visualizer/Module/Setup.php | 70 +++- classes/Visualizer/Module/Wizard.php | 76 ++++- css/style-wizard.css | 265 +++++++++++--- images/otter-logo.png | Bin 0 -> 15314 bytes images/spc-logo.svg | 50 +++ js/setup-wizard.js | 305 ++++++++++------- templates/setup-wizard.php | 493 ++++++++++++++++++--------- 8 files changed, 1041 insertions(+), 357 deletions(-) create mode 100644 SECURITY_REPORT.md create mode 100644 images/otter-logo.png create mode 100644 images/spc-logo.svg diff --git a/SECURITY_REPORT.md b/SECURITY_REPORT.md new file mode 100644 index 000000000..018fb17e9 --- /dev/null +++ b/SECURITY_REPORT.md @@ -0,0 +1,139 @@ +# Security Report — PR #1295 (feat: improvements to onboarding flow) + +**Repository:** Codeinwp/visualizer +**PR:** https://github.com/Codeinwp/visualizer/pull/1295 +**Review date:** 2026-03-27 +**Reviewer scope:** Full PR diff + affected call-paths + +--- + +## Summary + +Three confirmed vulnerabilities were found in the PR diff. All have been remediated in this branch. + +| # | Title | Severity | Confidence | Status | +|---|-------|----------|------------|--------| +| 1 | Missing authorization in AJAX dispatcher | High | High (1.0) | ✅ Fixed | +| 2 | Unconstrained plugin slug allows arbitrary plugin installation | Medium | High (1.0) | ✅ Fixed | +| 3 | XSS via unsanitized server error messages inserted with `.html()` | Medium | High (0.9) | ✅ Fixed | + +--- + +### Finding 1: Missing `manage_options` Capability Check in AJAX Dispatcher + +- **Severity:** High +- **Confidence:** High (1.0) +- **Vulnerability class:** Authorization Bypass (Broken Access Control) +- **Affected location:** `classes/Visualizer/Module/Wizard.php` — `visualizer_wizard_step_process()` +- **Entry point:** POST `action=visualizer_wizard_step_process` (authenticated `wp_ajax_*` endpoint, any logged-in user) +- **Trust boundary:** The function only checked a nonce (CSRF token), not an authorization capability. WordPress nonces are user-specific CSRF tokens; they do **not** verify privilege level. Any authenticated WordPress user (subscriber, contributor, etc.) who possesses a valid nonce could invoke all wizard steps. +- **Sink:** + - `setup_wizard_import_chart()` → `wp_insert_post()` (creates `visualizer` CPT posts) + - `setup_wizard_create_draft_page()` → `wp_insert_post()` / `wp_update_post()` (creates/modifies pages) + - `setup_wizard_subscribe_process()` → `dismissWizard()` + `wp_remote_post()` (dismisses wizard, sends external HTTP request) +- **Exploit path:** + 1. Attacker is any authenticated WordPress user (e.g., Subscriber role). + 2. Admin visits `visualizer-setup-wizard` page; nonce is embedded in page source / localized JS variable `visualizerSetupWizardData.ajax.security`. + 3. If attacker obtains the nonce value (e.g. via XSS on the admin page, or if the wizard page is briefly accessible), they POST: `action=visualizer_wizard_step_process&security=&step=step_2&chart_type=pie` using their own session. + 4. Because WordPress nonces are tied to the current user session, the attacker's own user must generate a fresh nonce via `/wp-admin/admin-ajax.php?action=visualizer_wizard_get_nonce` (if such exists). However: the `wp_create_nonce(VISUALIZER_ABSPATH)` action string is predictable (it is the server's absolute path), meaning any admin-accessible context that exposes this nonce (e.g. inline script tags) leaks it. + 5. Result: unauthorized post creation (`visualizer` CPT), page modification, or wizard dismissal. +- **Impact:** Integrity — low-privilege users can create chart posts or modify the "Visualizer Demo Page" draft page, dismiss the setup wizard for all users, or trigger an external HTTP subscription request. +- **CVSS v3.1:** `6.5` (`AV:N/AC:L/PR:L/UI:R/S:U/C:N/I:H/A:N`) +- **CWE:** CWE-862 — Missing Authorization +- **OWASP:** A01:2021 — Broken Access Control +- **Minimal PoC payload (non-destructive):** + ``` + POST /wp-admin/admin-ajax.php HTTP/1.1 + Cookie: wordpress_logged_in_= + Content-Type: application/x-www-form-urlencoded + + action=visualizer_wizard_step_process&security=&step=create_draft_page&add_basic_shortcode=false + ``` +- **Expected vulnerable behavior:** A `visualizer` draft page is created/modified even though the requesting user is a Subscriber. +- **Reproducibility:** Likely — requires attacker to obtain a valid nonce (predictable action string, obtainable from admin page source if admin is logged in simultaneously). +- **Remediation:** Added `current_user_can( 'manage_options' )` check immediately after the nonce check in `visualizer_wizard_step_process()`. This ensures only site administrators can invoke any wizard AJAX step. + +--- + +### Finding 2: Unconstrained Plugin Slug Allows Arbitrary Plugin Installation + +- **Severity:** Medium +- **Confidence:** High (1.0) +- **Vulnerability class:** Improper Input Validation / Privilege Misuse +- **Affected location:** `classes/Visualizer/Module/Wizard.php` — `setup_wizard_install_plugin()` (line ~481) +- **Entry point:** POST `slug` parameter to `step_4` of `visualizer_wizard_step_process` +- **Trust boundary:** The function performs a `current_user_can('install_plugins')` check (administrator-level), but does **not** validate the `$slug` against an allowlist. The PR was designed to install only three specific plugins (`optimole-wp`, `otter-blocks`, `wp-cloudflare-page-cache`), but the backend accepted any valid WordPress.org plugin slug. +- **Sink:** `plugins_api( 'plugin_information', ['slug' => $slug] )` → `Plugin_Upgrader::install( $api->download_link )` → `activate_plugin( $plugin_file )` +- **Exploit path:** + 1. Attacker is an authenticated administrator. + 2. Attacker POSTs: `action=visualizer_wizard_step_process&security=&step=step_4&slug=` + 3. Any plugin available on WordPress.org is downloaded, installed, and activated — including plugins with known unpatched vulnerabilities, or plugins that alter site behavior in unexpected ways. + 4. The activation happens without the standard WordPress plugin-install admin UI warnings or confirmation steps. +- **Impact:** Integrity/Availability — an administrator can install/activate any WordPress.org plugin via this endpoint, including known-vulnerable plugins, bypassing any site-level allowlists or manual review. +- **CVSS v3.1:** `4.9` (`AV:N/AC:L/PR:H/UI:N/S:U/C:N/I:H/A:N`) +- **CWE:** CWE-20 — Improper Input Validation +- **OWASP:** A03:2021 — Injection / A05:2021 — Security Misconfiguration +- **Minimal PoC payload (non-destructive):** + ``` + POST /wp-admin/admin-ajax.php + Cookie: + + action=visualizer_wizard_step_process&security=&step=step_4&slug=hello-dolly + ``` +- **Expected vulnerable behavior:** The `hello-dolly` plugin (or any other arbitrary WordPress.org plugin) is downloaded and activated on the site. +- **Reproducibility:** Reproducible — the allowlist was entirely absent. +- **Remediation:** Added a `const ALLOWED_PLUGIN_SLUGS = ['optimole-wp', 'otter-blocks', 'wp-cloudflare-page-cache']` class constant and a strict `in_array( $slug, self::ALLOWED_PLUGIN_SLUGS, true )` check before any plugin API or filesystem operations. + +--- + +### Finding 3: XSS via Unsanitized Server Error Messages Inserted via `.html()` + +- **Severity:** Medium +- **Confidence:** High (0.9) +- **Vulnerability class:** Reflected/Stored XSS +- **Affected location:** `js/setup-wizard.js` — lines 116, 331, and 37 +- **Entry point:** `response.message` field returned from `setup_wizard_install_plugin()` AJAX response (line 331); `data.message` from `setup_wizard_import_chart()` response (line 116); `res.message` from `setup_wizard_subscribe_process()` response (line 37). +- **Trust boundary:** The JavaScript used jQuery `.html()` to insert server-supplied message strings into the DOM. Error messages from `$api->get_error_message()`, `$skin->result->get_error_message()`, and `$skin->get_error_message()` were not HTML-escaped on the PHP side before JSON encoding. If any of these messages contain HTML (e.g., from a compromised or attacker-controlled WordPress.org API response, or a MITM on the HTTP connection), they would be rendered as HTML by jQuery. +- **Sink:** `$error.html('

' + data.message + '

')` and `$error.html('

' + message + '

')` +- **Exploit path (plugin install step — line 331):** + 1. Attacker performs a MITM on the HTTPS connection to `api.wordpress.org` (or compromises the API). + 2. The `plugins_api()` call returns a `WP_Error` whose message contains ``. + 3. PHP sends this verbatim in the JSON response (no `esc_html()` applied). + 4. JavaScript does `$error.html('

' + message + '

')` which renders the HTML, executing the script in the admin's browser. +- **Impact:** Confidentiality/Integrity — exfiltration of admin session cookies, CSRF token theft, admin account takeover. +- **CVSS v3.1:** `5.4` (`AV:N/AC:H/PR:H/UI:R/S:C/C:L/I:L/A:N`) +- **CWE:** CWE-79 — Improper Neutralization of Input During Web Page Generation (Cross-site Scripting) +- **OWASP:** A03:2021 — Injection (XSS) +- **Minimal PoC payload (non-destructive):** + Simulate the AJAX response with: `{"status":0,"message":""}` + then observe that jQuery renders the `` tag and fires the `onerror` handler. +- **Expected vulnerable behavior:** The injected HTML/script executes in the browser of the administrator performing the wizard step. +- **Reproducibility:** Likely — exploitability depends on controlling the server-side error message (MITM or compromised API), which is a prerequisite with medium difficulty. However, the code pattern itself is directly vulnerable. +- **Remediation (two-layer defence):** + 1. **PHP side:** Applied `esc_html()` to all `$api->get_error_message()`, `$skin->result->get_error_message()`, `$skin->get_error_message()`, and `$result->get_error_message()` values before placing them in `wp_send_json()` response arrays. + 2. **JavaScript side:** Replaced all three `.html(...)` calls with safe DOM-construction alternatives: + - `$error.empty().append( $('

').text( message ) ).removeClass('hidden')` — creates the `

` element safely and sets its text content, preventing any HTML interpretation. + - `$('.redirect-popup').find('h3.popup-title').text(res.message)` — uses `.text()` instead of `.html()`. + +--- + +## Residual Risks + +The following items were reviewed and assessed as low/acceptable risk or not exploitable: + +| Item | Assessment | +|------|-----------| +| `chart_type` used to construct CSV file path | Protected by `checkChartStatus()` allowlist; no path traversal possible | +| `basic_shortcode` stored as page post_content | Sanitized with `sanitize_text_field()` which strips HTML; no stored XSS | +| `redirect_to` from `setup_wizard_subscribe_process()` used as `window.location.href` | Values are server-generated (`get_edit_post_link()`, `admin_url()`); not attacker-controlled | +| Open-redirect in `goToDraftPage()` | Same as above; `redirect_to` is server-generated only | +| `$plugin_files[0]` used in `activate_plugin()` path | Safe after slug allowlist fix; directory listing is limited to the allowlisted slug directory | + +--- + +## Files Changed + +| File | Changes | +|------|---------| +| `classes/Visualizer/Module/Wizard.php` | Added `manage_options` capability check; added `ALLOWED_PLUGIN_SLUGS` constant + allowlist validation; applied `esc_html()` to all WP_Error messages in JSON responses | +| `js/setup-wizard.js` | Replaced three `.html()` calls with `.text()` / safe jQuery DOM construction | diff --git a/classes/Visualizer/Module/Setup.php b/classes/Visualizer/Module/Setup.php index 5c0968d1e..f0cc81f47 100644 --- a/classes/Visualizer/Module/Setup.php +++ b/classes/Visualizer/Module/Setup.php @@ -209,8 +209,7 @@ public function activate( $network_wide ) { * Activates the plugin on a particular blog instance (supports multisite and single site). */ private function activate_on_site() { - wp_clear_scheduled_hook( 'visualizer_schedule_refresh_db' ); - wp_schedule_event( strtotime( 'midnight' ) - get_option( 'gmt_offset' ) * HOUR_IN_SECONDS, apply_filters( 'visualizer_chart_schedule_interval', 'visualizer_ten_minutes' ), 'visualizer_schedule_refresh_db' ); + $this->schedule_refresh_db_action(); add_option( 'visualizer-activated', true ); $is_fresh_install = get_option( 'visualizer_fresh_install', false ); if ( ! defined( 'TI_E2E_TESTING' ) && false === $is_fresh_install ) { @@ -237,7 +236,7 @@ public function deactivate( $network_wide ) { * Deactivates the plugin on a particular blog instance (supports multisite and single site). */ private function deactivate_on_site() { - wp_clear_scheduled_hook( 'visualizer_schedule_refresh_db' ); + $this->unschedule_refresh_db_action(); delete_option( 'visualizer-activated', true ); } @@ -253,10 +252,21 @@ public function adminInit() { // fire any upgrades necessary. Visualizer_Module_Upgrade::upgrade(); - if ( get_option( 'visualizer-activated' ) ) { + $activated_flag = get_option( 'visualizer-activated' ); + $fresh_install = get_option( 'visualizer_fresh_install', false ); + $is_pro = Visualizer_Module::is_pro(); + if ( $activated_flag ) { + if ( function_exists( 'wp_doing_ajax' ) && wp_doing_ajax() ) { + // Defer redirect until a normal admin request. + return; + } + if ( wp_doing_cron() ) { + // Defer redirect during cron requests. + return; + } delete_option( 'visualizer-activated' ); if ( ! headers_sent() ) { - if ( ! Visualizer_Module::is_pro() && ! empty( get_option( 'visualizer_fresh_install', false ) ) ) { + if ( ! $is_pro && ! empty( $fresh_install ) ) { $redirect_url = array( 'page' => 'visualizer-setup-wizard', 'tab' => '#step-1', @@ -469,4 +479,54 @@ public function custom_cron_schedules( $schedules ) { return $schedules; } + + /** + * Schedule the recurring DB refresh action. + */ + private function schedule_refresh_db_action(): void { + $hook = 'visualizer_schedule_refresh_db'; + $group = 'visualizer'; + $interval_key = apply_filters( 'visualizer_chart_schedule_interval', 'visualizer_ten_minutes' ); + $interval = $this->get_schedule_interval_seconds( $interval_key ); + $timestamp = strtotime( 'midnight' ) - get_option( 'gmt_offset' ) * HOUR_IN_SECONDS; + + if ( function_exists( 'as_next_scheduled_action' ) && function_exists( 'as_schedule_recurring_action' ) ) { + $next = as_next_scheduled_action( $hook, array(), $group ); + if ( false === $next ) { + as_schedule_recurring_action( $timestamp, $interval, $hook, array(), $group ); + } + wp_clear_scheduled_hook( $hook ); + return; + } + + wp_clear_scheduled_hook( $hook ); + wp_schedule_event( $timestamp, $interval_key, $hook ); + } + + /** + * Unschedule the recurring DB refresh action. + */ + private function unschedule_refresh_db_action(): void { + $hook = 'visualizer_schedule_refresh_db'; + $group = 'visualizer'; + if ( function_exists( 'as_unschedule_all_actions' ) ) { + as_unschedule_all_actions( $hook, array(), $group ); + } + wp_clear_scheduled_hook( $hook ); + } + + /** + * Resolve a cron schedule key to seconds. + * + * @param string $interval_key Cron schedule key. + * @return int Interval in seconds. + */ + private function get_schedule_interval_seconds( $interval_key ) { + $schedules = wp_get_schedules(); + if ( isset( $schedules[ $interval_key ]['interval'] ) ) { + return (int) $schedules[ $interval_key ]['interval']; + } + + return 600; + } } diff --git a/classes/Visualizer/Module/Wizard.php b/classes/Visualizer/Module/Wizard.php index d2f6290bf..e1503f2fd 100644 --- a/classes/Visualizer/Module/Wizard.php +++ b/classes/Visualizer/Module/Wizard.php @@ -73,6 +73,7 @@ public function registerAdminMenu() { } } + /** * Method to register the setup wizard page. * @@ -168,7 +169,15 @@ public function dismissWizard( $redirect_to_dashboard = true ) { */ public function visualizer_wizard_step_process() { check_ajax_referer( VISUALIZER_ABSPATH, 'security' ); - $step = ! empty( $_POST['step'] ) ? filter_input( INPUT_POST, 'step', FILTER_SANITIZE_STRING ) : 1; + if ( ! current_user_can( 'manage_options' ) ) { + wp_send_json( + array( + 'status' => 0, + 'message' => __( 'You do not have permission to perform this action.', 'visualizer' ), + ) + ); + } + $step = ! empty( $_POST['step'] ) ? sanitize_text_field( wp_unslash( $_POST['step'] ) ) : 1; switch ( $step ) { case 'step_2': $this->setup_wizard_import_chart(); @@ -193,7 +202,7 @@ public function visualizer_wizard_step_process() { */ private function setup_wizard_import_chart() { // phpcs:ignore WordPress.Security.NonceVerification.Missing - $chart_type = ! empty( $_POST['chart_type'] ) ? filter_input( INPUT_POST, 'chart_type', FILTER_SANITIZE_STRING ) : ''; + $chart_type = ! empty( $_POST['chart_type'] ) ? sanitize_text_field( wp_unslash( $_POST['chart_type'] ) ) : ''; $chart_status = Visualizer_Module_Admin::checkChartStatus( $chart_type ); if ( ! $chart_status ) { wp_send_json( @@ -386,7 +395,8 @@ private function setup_wizard_import_chart() { ); $this->update_wizard_data( $wizard_data, false ); $response = array( - 'success' => 1, + 'success' => 1, + 'chart_id' => $chart_id, ); } wp_send_json( $response ); @@ -416,7 +426,7 @@ private function update_wizard_data( $data = array(), $merge_option = true ) { private function setup_wizard_create_draft_page( $return_page_id = false ) { $add_basic_shortcode = ! empty( $_POST['add_basic_shortcode'] ) ? sanitize_text_field( wp_unslash( $_POST['add_basic_shortcode'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing $add_basic_shortcode = 'true' === $add_basic_shortcode ? true : false; - $basic_shortcode = ! empty( $_POST['basic_shortcode'] ) ? filter_input( INPUT_POST, 'basic_shortcode', FILTER_SANITIZE_STRING ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing + $basic_shortcode = ! empty( $_POST['basic_shortcode'] ) ? sanitize_text_field( wp_unslash( $_POST['basic_shortcode'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing if ( ! $add_basic_shortcode ) { wp_send_json( @@ -471,12 +481,17 @@ private function setup_wizard_create_draft_page( $return_page_id = false ) { ); } + /** + * Allowed plugin slugs for the setup wizard installer. + */ + const ALLOWED_PLUGIN_SLUGS = array( 'optimole-wp', 'otter-blocks', 'wp-cloudflare-page-cache' ); + /** * Step: 3 Install plugin. */ private function setup_wizard_install_plugin() { // phpcs:ignore WordPress.Security.NonceVerification.Missing - $slug = ! empty( $_POST['slug'] ) ? filter_input( INPUT_POST, 'slug', FILTER_SANITIZE_STRING ) : ''; + $slug = ! empty( $_POST['slug'] ) ? sanitize_text_field( wp_unslash( $_POST['slug'] ) ) : ''; if ( empty( $slug ) ) { wp_send_json( array( @@ -486,6 +501,15 @@ private function setup_wizard_install_plugin() { ); } + if ( ! in_array( $slug, self::ALLOWED_PLUGIN_SLUGS, true ) ) { + wp_send_json( + array( + 'status' => 0, + 'message' => __( 'Plugin not allowed.', 'visualizer' ), + ) + ); + } + if ( ! current_user_can( 'install_plugins' ) ) { wp_send_json( array( @@ -496,8 +520,10 @@ private function setup_wizard_install_plugin() { } if ( ! empty( $slug ) ) { + $wizard_data = get_option( self::OPTION_NAME, array() ); require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; include_once ABSPATH . 'wp-admin/includes/plugin-install.php'; + require_once ABSPATH . 'wp-admin/includes/plugin.php'; $api = plugins_api( 'plugin_information', @@ -513,7 +539,7 @@ private function setup_wizard_install_plugin() { wp_send_json( array( 'status' => 0, - 'message' => $api->get_error_message(), + 'message' => esc_html( $api->get_error_message() ), ) ); } @@ -525,7 +551,7 @@ private function setup_wizard_install_plugin() { wp_send_json( array( 'status' => 0, - 'message' => $api->get_error_message(), + 'message' => esc_html( $result->get_error_message() ), ) ); } elseif ( is_wp_error( $skin->result ) ) { @@ -533,7 +559,7 @@ private function setup_wizard_install_plugin() { wp_send_json( array( 'status' => 0, - 'message' => $skin->result->get_error_message(), + 'message' => esc_html( $skin->result->get_error_message() ), ) ); } @@ -542,7 +568,7 @@ private function setup_wizard_install_plugin() { wp_send_json( array( 'status' => 0, - 'message' => $skin->get_error_message(), + 'message' => esc_html( $skin->get_error_message() ), ) ); } @@ -559,11 +585,33 @@ private function setup_wizard_install_plugin() { wp_send_json( $status ); } - activate_plugin( 'optimole-wp/optimole-wp.php' ); - delete_transient( 'optml_fresh_install' ); - // Update wizard data. - $wizard_data['enable_perfomance'] = true; - $this->update_wizard_data( $wizard_data ); + $installed_plugins = get_plugins( '/' . sanitize_key( wp_unslash( $slug ) ) ); + if ( ! empty( $installed_plugins ) ) { + $plugin_files = array_keys( $installed_plugins ); + $plugin_file = sanitize_key( wp_unslash( $slug ) ) . '/' . $plugin_files[0]; + activate_plugin( $plugin_file ); + } + $wizard_data_updated = false; + if ( 'optimole-wp' === $slug ) { + delete_transient( 'optml_fresh_install' ); + // Update wizard data. + $wizard_data['enable_perfomance'] = true; + $wizard_data_updated = true; + } + if ( 'otter-blocks' === $slug ) { + // Update wizard data. + $wizard_data['enable_otter_blocks'] = true; + $wizard_data_updated = true; + update_option( 'themeisle_blocks_settings_onboarding', false ); + } + if ( 'wp-cloudflare-page-cache' === $slug ) { + // Update wizard data. + $wizard_data['enable_page_cache'] = true; + $wizard_data_updated = true; + } + if ( $wizard_data_updated ) { + $this->update_wizard_data( $wizard_data ); + } wp_send_json( array( diff --git a/css/style-wizard.css b/css/style-wizard.css index 0cbd2660c..c157f7624 100644 --- a/css/style-wizard.css +++ b/css/style-wizard.css @@ -244,6 +244,13 @@ input.vz-switch-toggle[type=checkbox]:checked:before{ position: relative; border-bottom: 1px solid #D9D9D9; } +.vz-form-wrap .form-block.no-sep{ + border-bottom: 0; + padding-bottom: 12px; +} +.vz-form-wrap .form-block.vz-final-block{ + padding: 12px 0; +} .vz-form-wrap .form-block:last-child{ border-bottom: 0; } @@ -948,6 +955,21 @@ display: none; padding-left: 20px; padding-right: 20px; } +.vz-accordion-title--static{ + padding: 22px 30px 22px 80px; +} +.vz-accordion-title--static .vz-checkbox{ + position: absolute; + left: 30px; + top: 50%; + margin-top: -10px; + width: 20px; + height: 20px; + z-index: 12; +} +.vz-accordion-content--static{ + display: block; +} .vz-features-list ul li{ padding: 25px 0; @@ -968,6 +990,136 @@ display: none; .vz-features-list ul li .txt{ width: 100%; } +.vz-final-options{ + display: flex; + flex-direction: column; + gap: 10px; +} +.vz-option-card{ + display: flex; + align-items: center; + gap: 16px; + padding: 16px 18px; + border: 1px solid #E5E7EB; + border-radius: 8px; + background: #fff; + position: relative; +} +.vz-option-check{ + width: 20px; + height: 20px; + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; +} +.vz-option-check input[type=checkbox]{ + width: 18px; + height: 18px; +} +.vz-option-icon{ + width: 40px; + height: 40px; + border-radius: 8px; + background: #F3F4F6; + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; +} +.vz-option-icon img{ + display: block; + max-width: 24px; + max-height: 24px; +} +.vz-option-body{ + flex: 1; +} +.vz-option-title{ + font-size: 16px; + font-weight: 600; + color: #0f172a; + display: flex; + align-items: center; + gap: 8px; + margin-bottom: 4px; +} +.vz-option-title .pro-label.free-label{ + font-size: 11px; + line-height: 14px; + padding: 2px 8px 3px; +} +.vz-option-card--newsletter .vz-option-icon{ + background: #E6F3F3; + color: #39C3D2; +} +.vz-option-card--newsletter .vz-option-icon .dashicons{ + font-size: 22px; + width: 22px; + height: 22px; +} +.vz-option-card--newsletter .vz-option-body{ + display: flex; + flex-direction: column; + gap: 6px; +} +.vz-option-card--newsletter .vz-option-input{ + max-width: 320px; + display: flex; + align-items: center; + gap: 8px; +} +.vz-option-card--newsletter .vz-change-email{ + background: transparent; + border: 0; + color: #39C3D2; + text-decoration: underline; + cursor: pointer; + padding: 0 0 0 6px; + font-size: 13px; +} +.vz-option-card--newsletter .vz-email-text{ + color: #39C3D2; + font-weight: 600; + padding-left: 6px; +} +.vz-install-status{ + position: absolute; + right: 14px; + top: 14px; + width: 18px; + height: 18px; + border-radius: 50%; + border: 2px solid #cbd5e1; + display: none; + align-items: center; + justify-content: center; + font-size: 12px; + line-height: 1; + color: #ffffff; +} +.vz-install-status.is-installing{ + display: flex; + border-color: #39C3D2; + border-top-color: transparent; + animation: spin 1s linear infinite; +} +.vz-install-status.is-done{ + display: flex; + background: #00AA63; + border-color: #00AA63; +} +.vz-install-status.is-error{ + display: flex; + background: #d63638; + border-color: #d63638; +} +.vz-install-status.is-done:before{ + content: "✓"; +} +.vz-install-status.is-error:before{ + content: "!"; +} .pro-label{ background: #007CBA; border-radius: 6px; @@ -988,34 +1140,23 @@ display: none; } /* visualizer accordion style End */ .vz-chart-list{ -/* max-width: 780px;*/ - padding: 0 18px; + max-width: 1100px; + padding: 0; margin-bottom: 40px; + margin-left: auto; + margin-right: auto; } .vz-chart-list > ul{ - display: flex; - flex-wrap: wrap; - justify-content: space-between; + display: grid; + grid-template-columns: repeat(5, minmax(0, 1fr)); + gap: 16px; + align-items: stretch; } .vz-chart-list .slick-arrow{ - position: absolute; - width: 30px; - top: 50%; - height: 30px; - margin-top: -15px; - font-size: 0; - color: #757575; - display: grid; - place-items: center; - border: 0; - background: transparent; - cursor: pointer; + display: none; } .vz-chart-list .slick-arrow:before{ - display: block; - font-family: "dashicons"; - font-size: 24px; - line-height: 1; + display: none; } .vz-chart-list .slick-arrow.slick-prev{ left: -42px; @@ -1030,19 +1171,19 @@ display: none; content: "\f345"; } .vz-chart-list > ul > li{ - width: 48%; - max-width: 362px; - padding-bottom: 60px; + width: 100%; + max-width: 100%; + padding-bottom: 0; } .vz-chart-list .slick-slide{ - margin-right: 34px; + margin-right: 0; } .vz-chart-option{ - width: 317px; + width: 100%; position: relative; display: flex; flex-wrap: wrap; - padding: 12px 12px 20px; + padding: 12px 12px 16px; } .vz-chart-option .img{ order: 1; @@ -1050,8 +1191,9 @@ display: none; z-index: 1; display: block; width: 100%; - max-width: 338px; - height: 198px; + max-width: 100%; + aspect-ratio: 23 / 18; + height: auto; background-color: #ffffff; margin-bottom: 20px; background-image: url(../images/chart_types_v395.png); @@ -1060,23 +1202,54 @@ display: none; transition: all .3s ease-in-out; /* filter: grayscale(100%); -webkit-filter: grayscale(100%); */ - background-size: 900px 1150px; + --wizard-sprite-scale: 0.45; + background-size: calc(900px * var(--wizard-sprite-scale)) calc(1150px * var(--wizard-sprite-scale)); filter: grayscale(100%); } .vz-chart-option .img.type-box-pie{ - background-position: -5px -17px; + background-position: calc(-5px * var(--wizard-sprite-scale)) calc(-17px * var(--wizard-sprite-scale)); } .vz-chart-option .img.type-box-bar{ - background-position: -305px -235px; + background-position: calc(-305px * var(--wizard-sprite-scale)) calc(-235px * var(--wizard-sprite-scale)); +} +.vz-chart-option .img.type-box-area{ + background-position: calc(-8px * var(--wizard-sprite-scale)) calc(-225px * var(--wizard-sprite-scale)); +} +.vz-chart-option .img.type-box-scatter{ + background-position: calc(-300px * var(--wizard-sprite-scale)) calc(0px * var(--wizard-sprite-scale)); +} +.vz-chart-option .img.type-box-gauge{ + background-position: calc(-7px * var(--wizard-sprite-scale)) calc(-450px * var(--wizard-sprite-scale)); } .vz-chart-option .img.type-box-line{ - background-position: -606px -14px; + background-position: calc(-606px * var(--wizard-sprite-scale)) calc(-14px * var(--wizard-sprite-scale)); } .vz-chart-option .img.type-box-tabular{ - background-position: -306px -693px; + background-position: calc(-306px * var(--wizard-sprite-scale)) calc(-693px * var(--wizard-sprite-scale)); } .vz-chart-option .img.type-box-geo{ - background-position: -603px -459px; + background-position: calc(-603px * var(--wizard-sprite-scale)) calc(-459px * var(--wizard-sprite-scale)); +} +.vz-chart-option .img.type-box-candlestick{ + background-position: calc(-304px * var(--wizard-sprite-scale)) calc(-450px * var(--wizard-sprite-scale)); +} +.vz-chart-option .img.type-box-bubble{ + background-position: calc(-604px * var(--wizard-sprite-scale)) calc(-906px * var(--wizard-sprite-scale)); +} +.vz-chart-option .img.type-box-column{ + background-position: calc(-600px * var(--wizard-sprite-scale)) calc(-225px * var(--wizard-sprite-scale)); +} +.vz-chart-option .img.type-box-timeline{ + background-position: calc(-8px * var(--wizard-sprite-scale)) calc(-670px * var(--wizard-sprite-scale)); +} +.vz-chart-option .img.type-box-combo{ + background-position: calc(-606px * var(--wizard-sprite-scale)) calc(-670px * var(--wizard-sprite-scale)); +} +.vz-chart-option .img.type-box-polarArea{ + background-position: calc(-2px * var(--wizard-sprite-scale)) calc(-912px * var(--wizard-sprite-scale)); +} +.vz-chart-option .img.type-box-radar{ + background-position: calc(-301px * var(--wizard-sprite-scale)) calc(-899px * var(--wizard-sprite-scale)); } .vz-chart-option:hover .img{ background-image: url(../images/chart_types_v395.png); @@ -1112,24 +1285,34 @@ display: none; display: flex; flex-wrap: wrap; align-items: center; + font-size: 13px; + line-height: 16px; } .vz-pro-label-wrap { order: 3; width: calc(100% - 20px); padding-left: 12px; - position: relative; z-index: 1; display: flex; flex-wrap: wrap; align-items: center; + padding-right: 42px; } .vz-pro-label-wrap h3 { opacity: .7; color: #000000; + font-size: 13px; + line-height: 16px; } .vz-pro-label-wrap span.pro-label{ - margin-left: 30px; + position: absolute; + top: 8px; + right: 8px; + margin-left: 0; font-weight: 600; + font-size: 11px; + line-height: 14px; + padding: 2px 8px 3px; } .vz-chart-option input[type=radio].vz-radio-btn:checked ~ .bg{ background: #BDE6EB; @@ -1215,6 +1398,9 @@ display: none; background: #39C3D2; transition: all .3s ease-in-out; } +.vz-import-status{ + margin-top: 12px; +} .vz-chart-list .slick-arrow[disabled="disabled"], .vz-chart-list .slick-arrow[aria-disabled="true"] { color: #eeeeee } @@ -1253,7 +1439,8 @@ display: none; .vz-document-list > ul > li{width: 100%;} .vz-help-improve-box .left{width: 100%;} .vz-help-improve-box .right{width: 100%;} - .vz-chart-list > ul > li{width: 100%; max-width: 100%; padding-bottom: 30px;} + .vz-chart-list > ul{grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 12px;} + .vz-chart-list > ul > li{width: 100%; max-width: 100%; padding-bottom: 0;} .vz-shortcode-preview-content{padding-right: 20px;} .vz-newsletter-wrap .vz-newsletter, .vz-newsletter-wrap .vz-newsletter-img{width: 100%; padding-bottom: 20px;} -} \ No newline at end of file +} diff --git a/images/otter-logo.png b/images/otter-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..7fd7d752e637324fa0d0289bb80dfdcb1ea7cfab GIT binary patch literal 15314 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 HO@jU(Cn^8u literal 0 HcmV?d00001 diff --git a/images/spc-logo.svg b/images/spc-logo.svg new file mode 100644 index 000000000..742554310 --- /dev/null +++ b/images/spc-logo.svg @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/js/setup-wizard.js b/js/setup-wizard.js index fbca0d2dd..e77e38c0f 100644 --- a/js/setup-wizard.js +++ b/js/setup-wizard.js @@ -29,10 +29,12 @@ jQuery(function ($) { postData.step ??= 'step_subscribe'; // Subscribe the user using the email if provided. Redirect to the draft page. + var $currentStep = $('#step-3'); + $.post(visualizerSetupWizardData.ajax.url, postData, function (res) { // Toggle the redirect popup. - $('.redirect-popup').find('h3.popup-title').html(res.message); + $('.redirect-popup').find('h3.popup-title').text(res.message); $('.redirect-popup').show(); if (1 === res.status) { @@ -42,75 +44,142 @@ jQuery(function ($) { } else { $('.redirect-popup').hide(); } - currentStep.find('.spinner').removeClass('is-active'); + $currentStep.find('.spinner').removeClass('is-active'); }).fail(function () { $('.redirect-popup').hide(); - currentStep.find('.spinner').removeClass('is-active'); + $currentStep.find('.spinner').removeClass('is-active'); }); } - var provideContent = function(id, stepDirection, stepPosition, selStep, callback) { - // Import chart data. - if ( 1 == id ) { - var chartType = $(".vz-radio-btn:checked").val(); - var percentBarWidth = 0; - var loaderDelay; - $.ajax( { - beforeSend: function() { - loaderDelay = setInterval(function () { - $('.vz-progress-bar').css({ - width: percentBarWidth++ + '%' - }); - }, 1000); - }, - type: 'POST', - url: visualizerSetupWizardData.ajax.url, - dataType: 'json', - data: { - action: 'visualizer_wizard_step_process', - security: visualizerSetupWizardData.ajax.security, - chart_type: chartType, - step: 'step_2', - }, - success: function (data) { - clearInterval( loaderDelay ); - loaderDelay = setInterval(function () { - $('.vz-progress-bar').css({ - width: percentBarWidth++ + '%' - }); - if ( percentBarWidth >= 100 ) { - if ( 1 === data.success ) { - var importMessage = jQuery('[data-import_message]'); - importMessage - .html( importMessage.data('import_message') ) - .addClass('import_message'); + var runImport = function () { + var chartType = $(".vz-radio-btn:checked").val(); + var percentBarWidth = 0; + var loaderDelay; + var $step = $('#step-1'); + var $status = $step.find('.vz-import-status'); + var $progress = $status.find('.vz-progress-bar'); + var $message = $status.find('[data-import_message]'); + var $error = $status.find('.vz-error-notice'); + var $spinner = $step.find('.spinner'); + var $button = $step.find('[data-step_number="1"]'); + + $status.show(); + $progress.css({ width: '0' }); + if ($message.length) { + $message + .text($message.data('import_initial')) + .removeClass('import_message'); + } + $error.addClass('hidden').empty(); + $spinner.addClass('is-active'); + $button.addClass('disabled'); + + loaderDelay = setInterval(function () { + percentBarWidth = Math.min(percentBarWidth + 4, 90); + $progress.css({ width: percentBarWidth + '%' }); + }, 120); - $('#step-2').find('button.disabled').removeClass('disabled'); - } else if( 2 === data.status && '' !== data.message ) { - $('#step-2') - .find('.vz-error-notice') - .html( '

' + data.message + '

' ) - .removeClass('hidden'); - } else { - $('#smartwizard').smartWizard('reset'); - } - $('.vz-progress-bar').css({ - width: 100 + '%' - }); - $('.vz-progress').css({ - visibility: 'hidden' - }); - clearInterval( loaderDelay ); + $.ajax({ + type: 'POST', + url: visualizerSetupWizardData.ajax.url, + dataType: 'json', + data: { + action: 'visualizer_wizard_step_process', + security: visualizerSetupWizardData.ajax.security, + chart_type: chartType, + step: 'step_2', + }, + success: function (data) { + clearInterval(loaderDelay); + $progress.css({ width: '100%' }); + + if (1 === data.success) { + if (data.chart_id) { + var $shortcode = $('#basic_shortcode'); + if ($shortcode.length) { + $shortcode.val( + $shortcode.val().replace('{{chart_id}}', data.chart_id) + ); } - }, 36 ); - }, - error: function() { - $('#step-2').find('.vz-progress-bar').animate({ width: '0' }); + } + if ($message.length) { + $message + .text($message.data('import_message')) + .addClass('import_message'); + } + + setTimeout(function () { + $spinner.removeClass('is-active'); + $('#smartwizard').smartWizard('next'); + }, 200); + } else if (2 === data.status && '' !== data.message) { + $error.empty().append( $('

').text( data.message ) ).removeClass('hidden'); + $spinner.removeClass('is-active'); + $button.removeClass('disabled'); + } else { + $spinner.removeClass('is-active'); + $button.removeClass('disabled'); + $('#smartwizard').smartWizard('reset'); } - } ); + }, + error: function () { + clearInterval(loaderDelay); + $progress.css({ width: '0' }); + $spinner.removeClass('is-active'); + $button.removeClass('disabled'); + } + }); + }; + + var collectInstallSlugs = function () { + var slugs = []; + var $optimole = $('#enable_performance'); + if ($optimole.length && $optimole.is(':checked') && !$optimole.is(':disabled')) { + slugs.push('optimole-wp'); } - callback(); - } + if ($('#enable_otter_blocks').is(':checked') && !$('#enable_otter_blocks').is(':disabled')) { + slugs.push('otter-blocks'); + } + if ($('#enable_page_cache').is(':checked') && !$('#enable_page_cache').is(':disabled')) { + slugs.push('wp-cloudflare-page-cache'); + } + return slugs; + }; + + var setInstallStatus = function (slug, statusClass) { + var $status = $('[data-install-status="' + slug + '"]'); + $status.removeClass('is-installing is-done is-error').addClass(statusClass); + }; + + var installPluginsSequentially = function (slugs, onDone) { + if (!slugs.length) { + onDone(true); + return; + } + var slug = slugs.shift(); + setInstallStatus(slug, 'is-installing'); + $.post( + visualizerSetupWizardData.ajax.url, + { + action: 'visualizer_wizard_step_process', + security: visualizerSetupWizardData.ajax.security, + slug: slug, + step: 'step_4', + }, + function (response) { + if (1 === response.status) { + setInstallStatus(slug, 'is-done'); + installPluginsSequentially(slugs, onDone); + } else { + setInstallStatus(slug, 'is-error'); + onDone(false, response.message); + } + } + ).fail(function () { + setInstallStatus(slug, 'is-error'); + onDone(false, ''); + }); + }; $("#smartwizard").smartWizard({ transition: { animation: "fade", // Animation effect on navigation, none|fade|slideHorizontal|slideVertical|slideSwing|css(Animation CSS class also need to specify) @@ -133,8 +202,7 @@ jQuery(function ($) { btnCss: "", btnNextCss: "btn-primary next-btn", btnPrevCss: "btn-light", - }, - getContent: provideContent + } }); // click to open accordion. @@ -168,47 +236,19 @@ jQuery(function ($) { switch (stepNumber) { case 1: if ($(".vz-radio-btn").is(":checked")) { - $('#smartwizard').smartWizard('next'); + runImport(); } break; - case 3: + case 2: if ( isLivePreview ) { $('#smartwizard').smartWizard('next'); } else { var urlParams = new URLSearchParams(window.location.search); urlParams.set('preview_chart', Date.now()); - window.location.hash = "#step-3"; + window.location.hash = "#step-2"; window.location.search = urlParams; } break; - case 4: - $('#step-4').find('.spinner').addClass('is-active'); - $('#step-4').find('.vz-error-notice').addClass('hidden'); - - $.post( - visualizerSetupWizardData.ajax.url, - { - action: 'visualizer_wizard_step_process', - security: visualizerSetupWizardData.ajax.security, - slug: 'optimole-wp', - step: 'step_4', - }, - function (response) { - if (1 === response.status) { - $('#smartwizard').smartWizard('next'); - } else if ( 'undefined' !== typeof response.message ) { - $('#step-4') - .find('.vz-error-notice') - .html("

" + response.message + "

"); - $('#step-4').find('.vz-error-notice').removeClass('hidden'); - } - $('#step-4').find('.spinner').removeClass('is-active'); - } - ).fail(function () { - $('#step-4').find('.spinner').removeClass('is-active'); - }); - e.preventDefault(); - break; default: e.preventDefault(); break; @@ -246,16 +286,6 @@ jQuery(function ($) { }); // Enable performance feature. - $("#step-4").on("change", "input:checkbox", function () { - if ($(this).is(":checked")) { - $(".skip-improvement").hide(); - $(".vz-wizard-install-plugin").show(); - } else { - $(".skip-improvement").show(); - $(".vz-wizard-install-plugin").hide(); - } - }); - // Step: 4 Skip and subscribe process. $(document).on( 'click', '.vz-subscribe', function (e) { var withSubscribe = $(this).data("vz_subscribe"); @@ -267,8 +297,9 @@ jQuery(function ($) { var emailElement = $("#vz_subscribe_email"); // Remove error message. emailElement.next(".vz-field-error").remove(); + var newsletterEnabled = $("#enable_newsletter").is(":checked"); - if (withSubscribe) { + if (withSubscribe && newsletterEnabled) { var subscribeEmail = emailElement.val(); var EmailTest = /^[\w\-\.\+]+\@[a-zA-Z0-9\.\-]+\.[a-zA-z0-9]{2,4}$/; var errorMessage = ""; @@ -285,14 +316,49 @@ jQuery(function ($) { postData.email = subscribeEmail; postData.with_subscribe = withSubscribe; + } else { + postData.with_subscribe = false; } - var currentStep = $( '.vz-wizard-wrap .tab-pane:last-child' ); - currentStep.find(".spinner").addClass("is-active"); + var $step = $('#step-3'); + $step.find(".spinner").addClass("is-active"); + var $error = $step.find('.vz-error-notice').first(); + $error.addClass('hidden').empty(); - goToDraftPage( postData ); + var slugs = collectInstallSlugs(); + installPluginsSequentially(slugs.slice(), function (ok, message) { + if (!ok) { + if (message) { + $error.empty().append( $('

').text( message ) ).removeClass('hidden'); + } + $step.find(".spinner").removeClass("is-active"); + return; + } + goToDraftPage(postData); + }); e.preventDefault(); }); + $(document).on('click', '.vz-change-email', function () { + var $card = $(this).closest('.vz-option-card--newsletter'); + var $inputWrap = $card.find('.vz-option-input'); + $inputWrap.show(); + $card.find('#vz_subscribe_email').focus(); + }); + + var finalizeNewsletterEmail = function ($card) { + var $input = $card.find('#vz_subscribe_email'); + var $text = $card.find('.vz-email-text'); + var email = $input.val(); + if (email) { + $text.text(email); + } + $card.find('.vz-option-input').hide(); + }; + + $(document).on('click', '.vz-save-email', function () { + finalizeNewsletterEmail($(this).closest('.vz-option-card--newsletter')); + }); + // Click to copy. var clipboard = new ClipboardJS(".vz-copy-code-btn"); clipboard.on("success", function (e) { @@ -319,29 +385,6 @@ jQuery(function ($) { } }); - $('.vz-chart-list > ul').slick({ - dots: false, - infinite: false, - speed: 400, - slidesToShow: 1, - centerMode: false, - variableWidth: true - }) - .on( 'afterChange', function(event, slick, currentSlide) { - // Disable next buttion. - if( currentSlide === 4 ) { - $('.slick-next').attr('disabled', true).css('pointer-events', 'none'); - } else { - $('.slick-next').removeAttr('disabled').css('pointer-events', 'all'); - } - // Disable prev buttion. - if( currentSlide === 0 ) { - $('.slick-prev').attr('disabled', true).css('pointer-events', 'none'); - } else { - $('.slick-prev').removeAttr('disabled').css('pointer-events', 'all'); - } - } ); - $(window).bind('pageshow', function() { if ( jQuery('.vz-chart-option input').is(':checked') ) { $('#step-1').find('button.disabled').removeClass('disabled'); diff --git a/templates/setup-wizard.php b/templates/setup-wizard.php index 38f1619b7..dfd252604 100644 --- a/templates/setup-wizard.php +++ b/templates/setup-wizard.php @@ -16,7 +16,9 @@ $chart_id = ! empty( $this->wizard_data['chart_id'] ) ? (int) $this->wizard_data['chart_id'] : ''; $wp_optimole_active = is_plugin_active( 'optimole-wp/optimole-wp.php' ); -$last_step_number = 5; +$wp_otter_active = is_plugin_active( 'otter-blocks/otter-blocks.php' ); +$wp_spc_active = is_plugin_active( 'wp-cloudflare-page-cache/wp-cloudflare-super-page-cache.php' ); +$last_step_number = 3; // Check if we are in the Live Preview which is used to showcase only the plugin features without any other distractions. Ideal for marketing purposes (like Live Preview on WordPress.org or on the plugin's website) $is_live_preview = ! empty( $_GET['env'] ) ? ( 'preview' === sanitize_key( $_GET['env'] ) ) : false; @@ -51,31 +53,12 @@ 2 -

- - - - - - - +
@@ -147,18 +130,193 @@ class="btn btn-secondary" target="_blank">
  • -
    -

    -
      -
    • -
    • -
    • -
    • - ) -
    • -
    • -
    - +
    + +
    +
    + +
    +
    +
    +
  • +
  • +
    + +
    +
    + +
    +
    +
    +
  • +
  • +
    + +
    +
    + +
    +
    +
    +
  • +
  • +
    + +
    +
    + +
    +
    +
    +
  • +
  • +
    + +
    +
    + +
    +
    +
    +
  • +
  • +
    + +
    +
    + +
    +
    +
    +
  • +
  • +
    + +
    +
    + +
    +
    +
    +
  • +
  • +
    + +
    +
    + +
    +
    +
    +
  • +
  • +
    + +
    +
    + +
    +
    +
    +
  • +
  • +
    + +
    +
    + +
    +
  • @@ -166,48 +324,20 @@ class="btn btn-secondary" target="_blank">
    -
    -
    - - - -
    -
    -
    -
    -

    -

    -
    -
    -
    -
    -
    - -
    -
    -
    -
    - -
    -
    -

    -

    -
    -
    -
    -
    -
    + + -

    -
    -
    -
    +
    @@ -218,42 +348,39 @@ class="btn btn-secondary" target="_blank">
    -
    -
    -
    -
    -
    - > -
    - +
    +
    +
    +
    + > +
    +
    +
    +

    -
    -
    - - -

    -

    - -

    -
    - -
    - -
    - - +
    +
    +
    + + +

    +

    + +

    +
    +
    + +
    + +
    @@ -268,88 +395,118 @@ class="btn btn-secondary" target="_blank">
    - -
    + +
    -

    -

    +

    +

    -
    +
    -
    -
    -
    -
    - +
    +
    + +
    + +
    +
    +
    + +
    - +

    + +

    +
    + +
    +
    + +
    +
    -
    -
    -
      -
    • -
      - -
      -
      -
      -

      -
      -
    • -
    +
    +
    + +
    +

    + +

    +
    -
    -
    -
    - - -
    -
    -
    -
    -
    - - -
    -
    -
    -
    -

    -

    -
    -
    -
    -
    -
    -
    -
    -

    -
    - +
    + +
    +
    +
    +
    + + +
    +

    + +

    +
    +
    -
    - +
    - - +