); } if ( class_exists( 'Imagick' ) ) { // Add data for Imagick WebP, AVIF, HEIC and JPEG XL support. $query['image_support']['imagick'] = array_keys( array_filter( array( 'webp' => ! empty( Imagick::queryFormats( 'WEBP' ) ), 'avif' => ! empty( Imagick::queryFormats( 'AVIF' ) ), 'heic' => ! empty( Imagick::queryFormats( 'HEIC' ) ), 'jxl' => ! empty( Imagick::queryFormats( 'JXL' ) ), ) ) ); } /** * Filters the query arguments sent as part of the core version check. * * WARNING: Changing this data may result in your site not receiving security updates. * Please exercise extreme caution. * * @since 4.9.0 * @since 6.1.0 Added `$extensions`, `$platform_flags`, and `$image_support` to the `$query` parameter. * * @param array $query { * Version check query arguments. * * @type string $version WordPress version number. * @type string $php PHP version number. * @type string $locale The locale to retrieve updates for. * @type string $mysql MySQL version number. * @type string $local_package The value of the $wp_local_package global, when set. * @type int $blogs Number of sites on this WordPress installation. * @type int $users Number of users on this WordPress installation. * @type int $multisite_enabled Whether this WordPress installation uses Multisite. * @type int $initial_db_version Database version of WordPress at time of installation. * @type array $extensions List of PHP extensions and their versions. * @type array $platform_flags List containing the operating system name and bit support. * @type array $image_support List of image formats supported by GD and Imagick. * } */ $query = apply_filters( 'core_version_check_query_args', $query ); $post_body = array( 'translations' => wp_json_encode( $translations ), ); if ( is_array( $extra_stats ) ) { $post_body = array_merge( $post_body, $extra_stats ); } // Allow for WP_AUTO_UPDATE_CORE to specify beta/RC/development releases. if ( defined( 'WP_AUTO_UPDATE_CORE' ) && in_array( WP_AUTO_UPDATE_CORE, array( 'beta', 'rc', 'development', 'branch-development' ), true ) ) { $query['channel'] = WP_AUTO_UPDATE_CORE; } $url = 'http://api.wordpress.org/core/version-check/1.7/?' . http_build_query( $query, '', '&' ); $http_url = $url; $ssl = wp_http_supports( array( 'ssl' ) ); if ( $ssl ) { $url = set_url_scheme( $url, 'https' ); } $doing_cron = wp_doing_cron(); $options = array( 'timeout' => $doing_cron ? 30 : 3, 'user-agent' => 'WordPress/' . wp_get_wp_version() . '; ' . home_url( '/' ), 'headers' => array( 'wp_install' => $wp_install, 'wp_blog' => home_url( '/' ), ), 'body' => $post_body, ); $response = wp_remote_post( $url, $options ); if ( $ssl && is_wp_error( $response ) ) { wp_trigger_error( __FUNCTION__, sprintf( /* translators: %s: Support forums URL. */ __( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server’s configuration. If you continue to have problems, please try the support forums.' ), __( 'https://wordpress.org/support/forums/' ) ) . ' ' . __( '(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)' ), headers_sent() || WP_DEBUG ? E_USER_WARNING : E_USER_NOTICE ); $response = wp_remote_post( $http_url, $options ); } if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) { return; } $body = trim( wp_remote_retrieve_body( $response ) ); $body = json_decode( $body, true ); if ( ! is_array( $body ) || ! isset( $body['offers'] ) ) { return; } $offers = $body['offers']; foreach ( $offers as &$offer ) { foreach ( $offer as $offer_key => $value ) { if ( 'packages' === $offer_key ) { $offer['packages'] = (object) array_intersect_key( array_map( 'esc_url', $offer['packages'] ), array_fill_keys( array( 'full', 'no_content', 'new_bundled', 'partial', 'rollback' ), '' ) ); } elseif ( 'download' === $offer_key ) { $offer['download'] = esc_url( $value ); } else { $offer[ $offer_key ] = esc_html( $value ); } } $offer = (object) array_intersect_key( $offer, array_fill_keys( array( 'response', 'download', 'locale', 'packages', 'current', 'version', 'php_version', 'mysql_version', 'new_bundled', 'partial_version', 'notify_email', 'support_email', 'new_files', ), '' ) ); } $updates = new stdClass(); $updates->updates = $offers; $updates->last_checked = time(); $updates->version_checked = wp_get_wp_version(); if ( isset( $body['translations'] ) ) { $updates->translations = $body['translations']; } set_site_transient( 'update_core', $updates ); if ( ! empty( $body['ttl'] ) ) { $ttl = (int) $body['ttl']; if ( $ttl && ( time() + $ttl < wp_next_scheduled( 'wp_version_check' ) ) ) { // Queue an event to re-run the update check in $ttl seconds. wp_schedule_single_event( time() + $ttl, 'wp_version_check' ); } } // Trigger background updates if running non-interactively, and we weren't called from the update handler. if ( $doing_cron && ! doing_action( 'wp_maybe_auto_update' ) ) { /** * Fires during wp_cron, starting the auto-update process. * * @since 3.9.0 */ do_action( 'wp_maybe_auto_update' ); } } /** * Checks for available updates to plugins based on the latest versions hosted on WordPress.org. * * Despite its name this function does not actually perform any updates, it only checks for available updates. * * A list of all plugins installed is sent to api.wordpress.org, along with the site locale. * * Checks against the WordPress server at api.wordpress.org. Will only check * if WordPress isn't installing. * * @since 2.3.0 * * @global string $wp_version The WordPress version string. * * @param array $extra_stats Extra statistics to report to the WordPress.org API. */ function wp_update_plugins( $extra_stats = array() ) { if ( wp_installing() ) { return; } // If running blog-side, bail unless we've not checked in the last 12 hours. if ( ! function_exists( 'get_plugins' ) ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; } $plugins = get_plugins(); $translations = wp_get_installed_translations( 'plugins' ); $active = get_option( 'active_plugins', array() ); $current = get_site_transient( 'update_plugins' ); if ( ! is_object( $current ) ) { $current = new stdClass(); } $doing_cron = wp_doing_cron(); // Check for update on a different schedule, depending on the page. switch ( current_filter() ) { case 'upgrader_process_complete': $timeout = 0; break; case 'load-update-core.php': $timeout = MINUTE_IN_SECONDS; break; case 'load-plugins.php': case 'load-update.php': $timeout = HOUR_IN_SECONDS; break; default: if ( $doing_cron ) { $timeout = 2 * HOUR_IN_SECONDS; } else { $timeout = 12 * HOUR_IN_SECONDS; } } $time_not_changed = isset( $current->last_checked ) && $timeout > ( time() - $current->last_checked ); if ( $time_not_changed && ! $extra_stats ) { $plugin_changed = false; foreach ( $plugins as $file => $p ) { if ( ! isset( $current->checked[ $file ] ) || (string) $current->checked[ $file ] !== (string) $p['Version'] ) { $plugin_changed = true; } } if ( isset( $current->response ) && is_array( $current->response ) ) { foreach ( $current->response as $plugin_file => $update_details ) { if ( ! isset( $plugins[ $plugin_file ] ) ) { $plugin_changed = true; break; } } } // Bail if we've checked recently and if nothing has changed. if ( ! $plugin_changed ) { return; } } // Update last_checked for current to prevent multiple blocking requests if request hangs. $current->last_checked = time(); set_site_transient( 'update_plugins', $current ); $to_send = compact( 'plugins', 'active' ); $locales = array_values( get_available_languages() ); /** * Filters the locales requested for plugin translations. * * @since 3.7.0 * @since 4.5.0 The default value of the `$locales` parameter changed to include all locales. * * @param string[] $locales Plugin locales. Default is all available locales of the site. */ $locales = apply_filters( 'plugins_update_check_locales', $locales ); $locales = array_unique( $locales ); if ( $doing_cron ) { $timeout = 30; // 30 seconds. } else { // Three seconds, plus one extra second for every 10 plugins. $timeout = 3 + (int) ( count( $plugins ) / 10 ); } $options = array( 'timeout' => $timeout, 'body' => array( 'plugins' => wp_json_encode( $to_send ), 'translations' => wp_json_encode( $translations ), 'locale' => wp_json_encode( $locales ), 'all' => wp_json_encode( true ), ), 'user-agent' => 'WordPress/' . wp_get_wp_version() . '; ' . home_url( '/' ), ); if ( $extra_stats ) { $options['body']['update_stats'] = wp_json_encode( $extra_stats ); } $url = 'http://api.wordpress.org/plugins/update-check/1.1/'; $http_url = $url; $ssl = wp_http_supports( array( 'ssl' ) ); if ( $ssl ) { $url = set_url_scheme( $url, 'https' ); } $raw_response = wp_remote_post( $url, $options ); if ( $ssl && is_wp_error( $raw_response ) ) { wp_trigger_error( __FUNCTION__, sprintf( /* translators: %s: Support forums URL. */ __( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server’s configuration. If you continue to have problems, please try the support forums.' ), __( 'https://wordpress.org/support/forums/' ) ) . ' ' . __( '(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)' ), headers_sent() || WP_DEBUG ? E_USER_WARNING : E_USER_NOTICE ); $raw_response = wp_remote_post( $http_url, $options ); } if ( is_wp_error( $raw_response ) || 200 !== wp_remote_retrieve_response_code( $raw_response ) ) { return; } $updates = new stdClass(); $updates->last_checked = time(); $updates->response = array(); $updates->translations = array(); $updates->no_update = array(); foreach ( $plugins as $file => $p ) { $updates->checked[ $file ] = $p['Version']; } $response = json_decode( wp_remote_retrieve_body( $raw_response ), true ); if ( $response && is_array( $response ) ) { $updates->response = $response['plugins']; $updates->translations = $response['translations']; $updates->no_update = $response['no_update']; } // Support updates for any plugins using the `Update URI` header field. foreach ( $plugins as $plugin_file => $plugin_data ) { if ( ! $plugin_data['UpdateURI'] || isset( $updates->response[ $plugin_file ] ) ) { continue; } $hostname = wp_parse_url( sanitize_url( $plugin_data['UpdateURI'] ), PHP_URL_HOST ); /** * Filters the update response for a given plugin hostname. * * The dynamic portion of the hook name, `$hostname`, refers to the hostname * of the URI specified in the `Update URI` header field. * * @since 5.8.0 * * @param array|false $update { * The plugin update data with the latest details. Default false. * * @type string $id Optional. ID of the plugin for update purposes, should be a URI * specified in the `Update URI` header field. * @type string $slug Slug of the plugin. * @type string $version The version of the plugin. * @type string $url The URL for details of the plugin. * @type string $package Optional. The update ZIP for the plugin. * @type string $tested Optional. The version of WordPress the plugin is tested against. * @type string $requires_php Optional. The version of PHP which the plugin requires. * @type bool $autoupdate Optional. Whether the plugin should automatically update. * @type string[] $icons Optional. Array of plugin icons. * @type string[] $banners Optional. Array of plugin banners. * @type string[] $banners_rtl Optional. Array of plugin RTL banners. * @type array $translations { * Optional. List of translation updates for the plugin. * * @type string $language The language the translation update is for. * @type string $version The version of the plugin this translation is for. * This is not the version of the language file. * @type string $updated The update timestamp of the translation file. * Should be a date in the `YYYY-MM-DD HH:MM:SS` format. * @type string $package The ZIP location containing the translation update. * @type string $autoupdate Whether the translation should be automatically installed. * } * } * @param array $plugin_data Plugin headers. * @param string $plugin_file Plugin filename. * @param string[] $locales Installed locales to look up translations for. */ $update = apply_filters( "update_plugins_{$hostname}", false, $plugin_data, $plugin_file, $locales ); if ( ! $update ) { continue; } $update = (object) $update; // Is it valid? We require at least a version. if ( ! isset( $update->version ) ) { continue; } // These should remain constant. $update->id = $plugin_data['UpdateURI']; $update->plugin = $plugin_file; // WordPress needs the version field specified as 'new_version'. if ( ! isset( $update->new_version ) ) { $update->new_version = $update->version; } // Handle any translation updates. if ( ! empty( $update->translations ) ) { foreach ( $update->translations as $translation ) { if ( isset( $translation['language'], $translation['package'] ) ) { $translation['type'] = 'plugin'; $translation['slug'] = isset( $update->slug ) ? $update->slug : $update->id; $updates->translations[] = $translation; } } } unset( $updates->no_update[ $plugin_file ], $updates->response[ $plugin_file ] ); if ( version_compare( $update->new_version, $plugin_data['Version'], '>' ) ) { $updates->response[ $plugin_file ] = $update; } else { $updates->no_update[ $plugin_file ] = $update; } } $sanitize_plugin_update_payload = static function ( &$item ) { $item = (object) $item; unset( $item->translations, $item->compatibility ); return $item; }; array_walk( $updates->response, $sanitize_plugin_update_payload ); array_walk( $updates->no_update, $sanitize_plugin_update_payload ); set_site_transient( 'update_plugins', $updates ); } /** * Checks for available updates to themes based on the latest versions hosted on WordPress.org. * * Despite its name this function does not actually perform any updates, it only checks for available updates. * * A list of all themes installed is sent to api.wordpress.org, along with the site locale. * * Checks against the WordPress server at api.wordpress.org. Will only check * if WordPress isn't installing. * * @since 2.7.0 * * @global string $wp_version The WordPress version string. * * @param array $extra_stats Extra statistics to report to the WordPress.org API. */ function wp_update_themes( $extra_stats = array() ) { if ( wp_installing() ) { return; } $installed_themes = wp_get_themes(); $translations = wp_get_installed_translations( 'themes' ); $last_update = get_site_transient( 'update_themes' ); if ( ! is_object( $last_update ) ) { $last_update = new stdClass(); } $themes = array(); $checked = array(); $request = array(); // Put slug of active theme into request. $request['active'] = get_option( 'stylesheet' ); foreach ( $installed_themes as $theme ) { $checked[ $theme->get_stylesheet() ] = $theme->get( 'Version' ); $themes[ $theme->get_stylesheet() ] = array( 'Name' => $theme->get( 'Name' ), 'Title' => $theme->get( 'Name' ), 'Version' => $theme->get( 'Version' ), 'Author' => $theme->get( 'Author' ), 'Author URI' => $theme->get( 'AuthorURI' ), 'UpdateURI' => $theme->get( 'UpdateURI' ), 'Template' => $theme->get_template(), 'Stylesheet' => $theme->get_stylesheet(), ); } $doing_cron = wp_doing_cron(); // Check for update on a different schedule, depending on the page. switch ( current_filter() ) { case 'upgrader_process_complete': $timeout = 0; break; case 'load-update-core.php': $timeout = MINUTE_IN_SECONDS; break; case 'load-themes.php': case 'load-update.php': $timeout = HOUR_IN_SECONDS; break; default: if ( $doing_cron ) { $timeout = 2 * HOUR_IN_SECONDS; } else { $timeout = 12 * HOUR_IN_SECONDS; } } $time_not_changed = isset( $last_update->last_checked ) && $timeout > ( time() - $last_update->last_checked ); if ( $time_not_changed && ! $extra_stats ) { $theme_changed = false; foreach ( $checked as $slug => $v ) { if ( ! isset( $last_update->checked[ $slug ] ) || (string) $last_update->checked[ $slug ] !== (string) $v ) { $theme_changed = true; } } if ( isset( $last_update->response ) && is_array( $last_update->response ) ) { foreach ( $last_update->response as $slug => $update_details ) { if ( ! isset( $checked[ $slug ] ) ) { $theme_changed = true; break; } } } // Bail if we've checked recently and if nothing has changed. if ( ! $theme_changed ) { return; } } // Update last_checked for current to prevent multiple blocking requests if request hangs. $last_update->last_checked = time(); set_site_transient( 'update_themes', $last_update ); $request['themes'] = $themes; $locales = array_values( get_available_languages() ); /** * Filters the locales requested for theme translations. * * @since 3.7.0 * @since 4.5.0 The default value of the `$locales` parameter changed to include all locales. * * @param string[] $locales Theme locales. Default is all available locales of the site. */ $locales = apply_filters( 'themes_update_check_locales', $locales ); $locales = array_unique( $locales ); if ( $doing_cron ) { $timeout = 30; // 30 seconds. } else { // Three seconds, plus one extra second for every 10 themes. $timeout = 3 + (int) ( count( $themes ) / 10 ); } $options = array( 'timeout' => $timeout, 'body' => array( 'themes' => wp_json_encode( $request ), 'translations' => wp_json_encode( $translations ), 'locale' => wp_json_encode( $locales ), ), 'user-agent' => 'WordPress/' . wp_get_wp_version() . '; ' . home_url( '/' ), ); if ( $extra_stats ) { $options['body']['update_stats'] = wp_json_encode( $extra_stats ); } $url = 'http://api.wordpress.org/themes/update-check/1.1/'; $http_url = $url; $ssl = wp_http_supports( array( 'ssl' ) ); if ( $ssl ) { $url = set_url_scheme( $url, 'https' ); } $raw_response = wp_remote_post( $url, $options ); if ( $ssl && is_wp_error( $raw_response ) ) { wp_trigger_error( __FUNCTION__, sprintf( /* translators: %s: Support forums URL. */ __( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server’s configuration. If you continue to have problems, please try the support forums.' ), __( 'https://wordpress.org/support/forums/' ) ) . ' ' . __( '(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)' ), headers_sent() || WP_DEBUG ? E_USER_WARNING : E_USER_NOTICE ); $raw_response = wp_remote_post( $http_url, $options ); } if ( is_wp_error( $raw_response ) || 200 !== wp_remote_retrieve_response_code( $raw_response ) ) { return; } $new_update = new stdClass(); $new_update->last_checked = time(); $new_update->checked = $checked; $response = json_decode( wp_remote_retrieve_body( $raw_response ), true ); if ( is_array( $response ) ) { $new_update->response = $response['themes']; $new_update->no_update = $response['no_update']; $new_update->translations = $response['translations']; } // Support updates for any themes using the `Update URI` header field. foreach ( $themes as $theme_stylesheet => $theme_data ) { if ( ! $theme_data['UpdateURI'] || isset( $new_update->response[ $theme_stylesheet ] ) ) { continue; } $hostname = wp_parse_url( sanitize_url( $theme_data['UpdateURI'] ), PHP_URL_HOST ); /** * Filters the update response for a given theme hostname. * * The dynamic portion of the hook name, `$hostname`, refers to the hostname * of the URI specified in the `Update URI` header field. * * @since 6.1.0 * * @param array|false $update { * The theme update data with the latest details. Default false. * * @type string $id Optional. ID of the theme for update purposes, should be a URI * specified in the `Update URI` header field. * @type string $theme Directory name of the theme. * @type string $version The version of the theme. * @type string $url The URL for details of the theme. * @type string $package Optional. The update ZIP for the theme. * @type string $tested Optional. The version of WordPress the theme is tested against. * @type string $requires_php Optional. The version of PHP which the theme requires. * @type bool $autoupdate Optional. Whether the theme should automatically update. * @type array $translations { * Optional. List of translation updates for the theme. * * @type string $language The language the translation update is for. * @type string $version The version of the theme this translation is for. * This is not the version of the language file. * @type string $updated The update timestamp of the translation file. * Should be a date in the `YYYY-MM-DD HH:MM:SS` format. * @type string $package The ZIP location containing the translation update. * @type string $autoupdate Whether the translation should be automatically installed. * } * } * @param array $theme_data Theme headers. * @param string $theme_stylesheet Theme stylesheet. * @param string[] $locales Installed locales to look up translations for. */ $update = apply_filters( "update_themes_{$hostname}", false, $theme_data, $theme_stylesheet, $locales ); if ( ! $update ) { continue; } $update = (object) $update; // Is it valid? We require at least a version. if ( ! isset( $update->version ) ) { continue; } // This should remain constant. $update->id = $theme_data['UpdateURI']; // WordPress needs the version field specified as 'new_version'. if ( ! isset( $update->new_version ) ) { $update->new_version = $update->version; } // Handle any translation updates. if ( ! empty( $update->translations ) ) { foreach ( $update->translations as $translation ) { if ( isset( $translation['language'], $translation['package'] ) ) { $translation['type'] = 'theme'; $translation['slug'] = isset( $update->theme ) ? $update->theme : $update->id; $new_update->translations[] = $translation; } } } unset( $new_update->no_update[ $theme_stylesheet ], $new_update->response[ $theme_stylesheet ] ); if ( version_compare( $update->new_version, $theme_data['Version'], '>' ) ) { $new_update->response[ $theme_stylesheet ] = (array) $update; } else { $new_update->no_update[ $theme_stylesheet ] = (array) $update; } } set_site_transient( 'update_themes', $new_update ); } /** * Performs WordPress automatic background updates. * * Updates WordPress core plus any plugins and themes that have automatic updates enabled. * * @since 3.7.0 */ function wp_maybe_auto_update() { require_once ABSPATH . 'wp-admin/includes/admin.php'; require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; $upgrader = new WP_Automatic_Updater(); $upgrader->run(); } /** * Retrieves a list of all language updates available. * * @since 3.7.0 * * @return object[] Array of translation objects that have available updates. */ function wp_get_translation_updates() { $updates = array(); $transients = array( 'update_core' => 'core', 'update_plugins' => 'plugin', 'update_themes' => 'theme', ); foreach ( $transients as $transient => $type ) { $transient = get_site_transient( $transient ); if ( empty( $transient->translations ) ) { continue; } foreach ( $transient->translations as $translation ) { $updates[] = (object) $translation; } } return $updates; } /** * Collects counts and UI strings for available updates. * * @since 3.3.0 * * @return array { * Fetched update data. * * @type int[] $counts An array of counts for available plugin, theme, and WordPress updates. * @type string $update_title Titles of available updates. * } */ function wp_get_update_data() { $counts = array( 'plugins' => 0, 'themes' => 0, 'wordpress' => 0, 'translations' => 0, ); $plugins = current_user_can( 'update_plugins' ); if ( $plugins ) { $update_plugins = get_site_transient( 'update_plugins' ); if ( ! empty( $update_plugins->response ) ) { $counts['plugins'] = count( $update_plugins->response ); } } $themes = current_user_can( 'update_themes' ); if ( $themes ) { $update_themes = get_site_transient( 'update_themes' ); if ( ! empty( $update_themes->response ) ) { $counts['themes'] = count( $update_themes->response ); } } $core = current_user_can( 'update_core' ); if ( $core && function_exists( 'get_core_updates' ) ) { $update_wordpress = get_core_updates( array( 'dismissed' => false ) ); if ( ! empty( $update_wordpress ) && ! in_array( $update_wordpress[0]->response, array( 'development', 'latest' ), true ) && current_user_can( 'update_core' ) ) { $counts['wordpress'] = 1; } } if ( ( $core || $plugins || $themes ) && wp_get_translation_updates() ) { $counts['translations'] = 1; } $counts['total'] = $counts['plugins'] + $counts['themes'] + $counts['wordpress'] + $counts['translations']; $titles = array(); if ( $counts['wordpress'] ) { /* translators: %d: Number of available WordPress updates. */ $titles['wordpress'] = sprintf( __( '%d WordPress Update' ), $counts['wordpress'] ); } if ( $counts['plugins'] ) { /* translators: %d: Number of available plugin updates. */ $titles['plugins'] = sprintf( _n( '%d Plugin Update', '%d Plugin Updates', $counts['plugins'] ), $counts['plugins'] ); } if ( $counts['themes'] ) { /* translators: %d: Number of available theme updates. */ $titles['themes'] = sprintf( _n( '%d Theme Update', '%d Theme Updates', $counts['themes'] ), $counts['themes'] ); } if ( $counts['translations'] ) { $titles['translations'] = __( 'Translation Updates' ); } $update_title = $titles ? esc_attr( implode( ', ', $titles ) ) : ''; $update_data = array( 'counts' => $counts, 'title' => $update_title, ); /** * Filters the returned array of update data for plugins, themes, and WordPress core. * * @since 3.5.0 * * @param array $update_data { * Fetched update data. * * @type int[] $counts An array of counts for available plugin, theme, and WordPress updates. * @type string $update_title Titles of available updates. * } * @param array $titles An array of update counts and UI strings for available updates. */ return apply_filters( 'wp_get_update_data', $update_data, $titles ); } /** * Determines whether core should be updated. * * @since 2.8.0 */ function _maybe_update_core() { $current = get_site_transient( 'update_core' ); if ( isset( $current->last_checked, $current->version_checked ) && 12 * HOUR_IN_SECONDS > ( time() - $current->last_checked ) && wp_get_wp_version() === $current->version_checked ) { return; } wp_version_check(); } /** * Checks the last time plugins were run before checking plugin versions. * * This might have been backported to WordPress 2.6.1 for performance reasons. * This is used for the wp-admin to check only so often instead of every page * load. * * @since 2.7.0 * @access private */ function _maybe_update_plugins() { $current = get_site_transient( 'update_plugins' ); if ( isset( $current->last_checked ) && 12 * HOUR_IN_SECONDS > ( time() - $current->last_checked ) ) { return; } wp_update_plugins(); } /** * Checks themes versions only after a duration of time. * * This is for performance reasons to make sure that on the theme version * checker is not run on every page load. * * @since 2.7.0 * @access private */ function _maybe_update_themes() { $current = get_site_transient( 'update_themes' ); if ( isset( $current->last_checked ) && 12 * HOUR_IN_SECONDS > ( time() - $current->last_checked ) ) { return; } wp_update_themes(); } /** * Schedules core, theme, and plugin update checks. * * @since 3.1.0 */ function wp_schedule_update_checks() { if ( ! wp_next_scheduled( 'wp_version_check' ) && ! wp_installing() ) { wp_schedule_event( time(), 'twicedaily', 'wp_version_check' ); } if ( ! wp_next_scheduled( 'wp_update_plugins' ) && ! wp_installing() ) { wp_schedule_event( time(), 'twicedaily', 'wp_update_plugins' ); } if ( ! wp_next_scheduled( 'wp_update_themes' ) && ! wp_installing() ) { wp_schedule_event( time(), 'twicedaily', 'wp_update_themes' ); } } /** * Clears existing update caches for plugins, themes, and core. * * @since 4.1.0 */ function wp_clean_update_cache() { if ( function_exists( 'wp_clean_plugins_cache' ) ) { wp_clean_plugins_cache(); } else { delete_site_transient( 'update_plugins' ); } wp_clean_themes_cache(); delete_site_transient( 'update_core' ); } /** * Schedules the removal of all contents in the temporary backup directory. * * @since 6.3.0 */ function wp_delete_all_temp_backups() { /* * Check if there is a lock, or if currently performing an Ajax request, * in which case there is a chance an update is running. * Reschedule for an hour from now and exit early. */ if ( get_option( 'core_updater.lock' ) || get_option( 'auto_updater.lock' ) || wp_doing_ajax() ) { wp_schedule_single_event( time() + HOUR_IN_SECONDS, 'wp_delete_temp_updater_backups' ); return; } // This action runs on shutdown to make sure there are no plugin updates currently running. add_action( 'shutdown', '_wp_delete_all_temp_backups' ); } /** * Deletes all contents in the temporary backup directory. * * @since 6.3.0 * * @access private * * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass. */ function _wp_delete_all_temp_backups() { global $wp_filesystem; if ( ! function_exists( 'WP_Filesystem' ) ) { require_once ABSPATH . 'wp-admin/includes/file.php'; } ob_start(); $credentials = request_filesystem_credentials( '' ); ob_end_clean(); if ( false === $credentials || ! WP_Filesystem( $credentials ) ) { wp_trigger_error( __FUNCTION__, __( 'Could not access filesystem.' ) ); return; } if ( ! $wp_filesystem->wp_content_dir() ) { wp_trigger_error( __FUNCTION__, /* translators: %s: Directory name. */ sprintf( __( 'Unable to locate WordPress content directory (%s).' ), 'wp-content' ) ); return; } $temp_backup_dir = $wp_filesystem->wp_content_dir() . 'upgrade-temp-backup/'; $dirlist = $wp_filesystem->dirlist( $temp_backup_dir ); $dirlist = $dirlist ? $dirlist : array(); foreach ( array_keys( $dirlist ) as $dir ) { if ( '.' === $dir || '..' === $dir ) { continue; } $wp_filesystem->delete( $temp_backup_dir . $dir, true ); } } if ( ( ! is_main_site() && ! is_network_admin() ) || wp_doing_ajax() ) { return; } add_action( 'admin_init', '_maybe_update_core' ); add_action( 'wp_version_check', 'wp_version_check' ); add_action( 'load-plugins.php', 'wp_update_plugins' ); add_action( 'load-update.php', 'wp_update_plugins' ); add_action( 'load-update-core.php', 'wp_update_plugins' ); add_action( 'admin_init', '_maybe_update_plugins' ); add_action( 'wp_update_plugins', 'wp_update_plugins' ); add_action( 'load-themes.php', 'wp_update_themes' ); add_action( 'load-update.php', 'wp_update_themes' ); add_action( 'load-update-core.php', 'wp_update_themes' ); add_action( 'admin_init', '_maybe_update_themes' ); add_action( 'wp_update_themes', 'wp_update_themes' ); add_action( 'update_option_WPLANG', 'wp_clean_update_cache', 10, 0 ); add_action( 'wp_maybe_auto_update', 'wp_maybe_auto_update' ); add_action( 'init', 'wp_schedule_update_checks' ); add_action( 'wp_delete_temp_updater_backups', 'wp_delete_all_temp_backups' ); ۖ7 ZSۻLɺ-jvۻm/$ Jf3U*q8kyy82_DLXz-K @٧_~͏߿"h>?z ϵMӨ={,]Y-Z~r,xP:x"#-{b9'GO/Iywi\4.NNS%ͲBh}uI 38c>Dp>ɐ;ތk]w:ҵ4֙Q?)huF?64Ux/ͷ7; N6lZrB3W]@&&@ ^ڽ'J0>i0"{g~`uwAol{ T)_F4>D(jGdd~R)٧E,ND #g弧3rDK-)ѷÈ;Wr"(w~0bRM, ۊ;ŀP.CG^ӥCoE&H$6ө3 >mlJk3/V#5 놿t})/6;U58N04Lz^qTranWx 2 QK0bbD4LnV+;3=fr[U^\9~6=uE`Xeo^F;^'(FVfqfRdk6{Tc$5͆´7.>Ʈ n:\< Zܬ&.#n(lv;o_tz=+ʌ}'uj - f"Z[7nk!LPNgI R7ok gBcXT%q~}t 9ŠlQsk ARxD$I h LlCƅ ێK4ɛ;&tކ!V#5 O=ǡ;_4Iv'.m.HZ% @ģ^>?_0 ~ؗ$ "15CBH?+* ##z_PvVx"g+̭T23C΃=ӈp'LαSKT[Ċ؆|;v..A?' 3N->>v_L9.Ґ@mXDn\#(ʋ@/yCWkv}h6ކ v5fazxB]nk:uByvo1OhH(( 6T$CnK="]==o*Rw DnA@|A /ZB"peѱfTb _lߛYkEB[Ll2Y=nV^V=y4< 9N߳3e[cN. X7o:nuToޭ`66-ƿ"s |BUQR>&N6*veW“YחέCn[V5hjA#.gv} ԇ:G v+ Ni3~??j%lй|ry=; 1INܾt8^ Ec*.؏`rBkf7iR*[Ѓaf\vHtJʞh`h':3t:^T+g& ro͗5찹={?~jmPlӕ&]MhT@#V%C#Z T !Y 22(B&@ۆll>kas<˚Q䯐847?xqnlhnLAm2YcdKàRuA"ť+NM5,ZS; \:.[LX [e$ݫRI~a5$P ^Isݑux.%hwGZ16 Lm8wKrCN2kha}f.w {G|@ >* "[Z4dO'U)aP1@l:atfsGdF;KwF}3&z],z1vn@d`$I`1OF5&tyNs)-1ntN|7Ni@ rث ap6;)0qvDb-Tx)5ؔ(n_jJС9kF_Y㷸u¾fB`z2hv/eO}6`e1qlV sfCqJz2p`8  8{4 Իϓ4h`p<+% W>eP:#HR1޼+i ꎆ)S@`a8P*lTb.^\P^ҖG 'q5d?%Ҁ;`mxuqG K'&EςbR1iJh< .]a%#(? C[hEgN^Tf3**..6eE VsI: |N>+2:+(2"݂!淆%FPhA3(o Ca32Y3β<;6 ?LwDמQ5jjÿ:mT7e!WV?3uOIAn^ b/%HZb9樓(#0gЀdO'$IpEo㤅+XH >+` fT(w& 3Qhdr{lkwۅɇ5CE2 N!V&BHl5z3N\[FSp! Y *KJ9W F31hbPҘxL ^&Z77J 랢 `NJ#1 J% d j8~i\ uLĿAlD蕐Nxy̜b^y~)0Xle획\I6#%dQVd)1nS_g\P R*F{|BHZu"($#Ibl"S۝3:+k)O~{3:=L;n^C G]$~2yNUVepm[W^*ce 03QE8Iyd\VR˼9X nث VԂnk]KڐjyZjER)ߺ`Zp P^y]rD%C,Hxj!-ԗ0iAr WFjs#̚uûVY=2u3\8xuY 2nei{0Y˰}Gv=Td־VKVݕ2j&reSɑijOš$MV>‡ST1|ai_OegMkAx!AfTa !yvfR06s2>>;9M6/ Q?q5Y+xOZ;̣ą|Ľyu㨸naX7+/473"͘}$S~]vVѕ^⎏KJcqfni{~GmǛ { -(\ZVq$}1v,ů#:c{j0iх5ơ4`abg٨t;z`g2ӴGo-^=$xK$O/YK~s Y qWmBYU/—֒b֎șok`hY;;7&1ZG/6W'0Er9G8S߯g]=^]Gn{q mڵzN }>:d4i{=a&ãQsҜ8&t6x[Mv~5g&ܟͽ&9Qs3&N&li.e7r\Ji:M`dd@%ܦ6M4fhM&x ?h Y7in&:9*(!|.|veĽ&r;:q\;D[?k/;YLuwۍ iazƣ;iHezƥ=Qx?D?D6ah4hD:ǂearAC9>˹?݄ۄ;`~-"v;HYlŽ]HwCP^Djڡ+nua?]zizm3s89e#$P~"plBi4p2G~:2&;v |,a%. gZ0ԗ'pf{epsbP&օI 䯉k{.)`@9TImlT9!XIOc\"kj#o_Rv%O_Νwt=j%Bv,72Asqb8%nrWH~'f,2M\b9tǤ.N_7H;ڽG@ _]2"Q92{/Oh"-L3WY!lT"5x1 F|&v Aɼ,D1}1";7 $ǿSeOJ0/u@JcPNaF[UXȏm,9`a68Sܟ5]p)Wo,rxrZSċM ]َo)j_@@X=9+$YPz\P4_d 1VbSlO{ vzyڧ 2w;]㔸s8EATG̚iS%oW Jr7 DZV2xftZ)EqSUeҸ )d<꩝ccTMQ$eDkOc?-ۍZ0k`-`Ob7[KC!l1-VҌ_{̘@dY>R˔gn\ ܮuL`49%J$mp%:O~%eAzߘ8F v]⌅nj LW51{X%][7[)kO!ˍow}*9֣V W;NJ#dG xݡڰ/4s0\Yɼ2+ɐm(, m1{4IQ|1(SCSepȡ tr*טJL#/>ş*iQoagE l["-@qe{a.om؏r J‡Mw/iz3tM==bKҧ}?k*.;qQ\_a)ZN?_JK!Q,-0҈H*l.gpU\|_7BY6u`Z%cfuZML&'Ţ?;EČ'yJV!;Ә=c3p)X5fiXYhKQ}d>EPSUTK ԋ}Zz`bLtᅑlmW!kVVMC=TYl(3Bggz 3Hť&`6rM29*o 1*nܓC $Zn%: Z?o7$wT2r{kJ)A!M)*J%R'24Z|^$ck cߨy>=F`$ r[p#޻IMA'?3p-gid`ҟVmfF&`ҊZP ۗIՏRR i⁓1 6gqj=tZ.yjl O3)|cNDY h/`^$+4E@2i3رѴ@Űt}<-25#%V A JRϜL.#!x3<nAr|mt`'frGJ,D:E)`IǷ y ?~5yO,aq NPt3:D33Z9)UR/FS%/>X5&E~oڷ<'+AŊ"iæctL:`= 5M=f{lg!#;i4S)83Hk^&f qoɁBrCMB;Íu ?C(mme݅آ4 Wl;h#݄t 9jb@VwxzUDt`_HCt:,ׂSv;[ O gffɗ Ǫ[ш1dݣ z8d$+FՓen?%{ ;3%T:#6n uz!2ݕ졹$N~Zb ˼>kiRo! cvwdh&[(ԛ閲?l\n`AS[Xհٸ[T8*M2E^IQIUP/~SfV3S>XZnkf.3{ iT /3>Yvz84%=VR73MGD֮77MGDn_[9LLfQ67;4MGDnn6qhJeYMan*RTU^^F?/c1 zX$Ec2ǭWVG)OpjH~-uء3EKB,1GEɴtf3nvdfjwu7uM,Yy9gVIN;Wn k7CQf_7 e,%xema߽tA*T5m܁蝆a+ NcXJZb({-=I "Noe;ʜpNRdTjk-^|oL@Nc'u9 doدG`ӄb?5U> $2@@[Up|m';\#0$ J-%B"jt1ҿF^G{D7YM ڨyxdgIvX0ɤ)2"ej̦$'$Kmwpjm!Ɓz B$l hZ8Sk3~.Q|-I%Tm^wFKDLgוZ]Og7?9܍L<۝˟ bқ:-`ϣ\@!2*a뉵YρB˟1B ԖQbYĎ \ZZ|K! "`q%_'RӒXUn4"gn7MBGUi,$͜]\-elWX=a.Ts97Gb@0ӝ<>b$UQۉȪr)fcL7\A?N| Na\k{ɶ)(RJ٭Gblv{|j-ocfJǮ 69k@?=t~4Q`$T4NMBC0ۓ9fe:-}bc k-z&+yLK{1Euh~UĕY tr`QŰęYQQňY^C0Y~!0"E1oZ0: >jZ@hAJ  zmh\"+9N&EtWs\NT7z+~d)#c;c⠏UjNЀY#l kjs1n L'k|E@YW2Z+U_ j` Y ZJXrb+-Brkr#ҥg.neKZ"?wYCXwlUcŒל^\[-gU:,UU&H`dzhT#`Z[8GeY2kw;Ý[MDL/gsųa_[@KG x"Vcg\GX}ӗ"Nւ;eF7z駥#.Orc7Ag[ӛ8JWPNJ Sܼ`c _eN|6!mC͆Ǟ p6 wPUfZ>>Ԅ,GyRB33SX`a6djїg $j8>dm39u1{[{a[D_8LASq3)˔|ުҌʌjtR=^%T,9+<r&V '"ҖJF&-0!s2TrT2 pb妀4{+Y!;(SE.UL* u\29erjyvKU痪zMQUŭWڛx,T+nyL_gIURSWXJ߰BBK%nli-BK% lhȜ-2Q00bM1 4 yoEr5sQ#WKaaC&kmJ<M0fYJx‚hj0neHeL .I͂5*B/"9nY3|B3frfLF>++4ӭQ,J1 Dsu-P=kݷoa cL36dJ^})M*_~`U)(l%S|me,'V\hJRi Uq]HAiR$RA&I}TSUL)s>n'[`n<1VTKlUEֻrd^&1la?Wll 80~%fht0{=)ߢteEt4L&_ UF"*-VZ^pXK:*T RhWE=*bLT{ AѬ^kb/E29$PRvJdb/e>ς.: 宨J9hW>R Zժ羨|doQ$BI}TEՍ5.>H#In$D1P9T!~{s~ SN .U]O[*W~=RWkѯCJyJuK:\Z* ~^߬&{ Bꎁb81S9]~W;k['Ր<-BFg"Pg]'Lr6+tO!QGs'Hƽc1e/ qlWg m }Xvxjt\W{8K\@QЉ߀H8qWEC0IiFUk!Jw)WYpY]5V"~qxy.l-|w>*,;ɓ֝^=`n?c{;Y虬ZEB0Y#sbB,5a ;ՋmE+cIOubJsYS!ܢl\~ U|h S )h9=nE\Ikڙe V!Ъ*I!u#|ZWlE<$H[gWZ~ti^* q!ԸTzB#Y@wËJv^ط҂yV;wWS\Sr4WAPeJqkh`ə`!zGHeC.CQm0O/4lيe+*!$yb_og^zU۪!(R`-yP3Z"_d7[3Dsu~3!Ib@KCS:_)rh5H2&u}feGYqm_|?Z"|ۋآ>Nv\?[6X`Tmo(;tP.:bV]ۛ>hEA?XpmW)TJ=q[Tek9ّ%[( ƶ`jJi.} |'a3E|kOe|Vc!'UfAOgQ󀢈ө*}`\B(W -V= XBVg^X 1@vPdg&K3ZrK>q *sɱ+0[4kPrXn{JmS&x!0`'FWSjfnw>W} *DVi cIIg5* ^fHIFuר.&~26W ;yƉ|SZMj;؎^e9>uCU +s &B/"SjTRɜF+%>ٺH~j;l҆.ܨX ^ ^y/Ep!kvl2݋So9R;A{sv`zph6 f} Q Z< D_Wga.k,;qΰFa<}mnV5u1zcٷTPkl<~QRՐm/D[)Ň7<.>|i(ݯ8Į A[=&7ux Pg7ԄmXKx+ {=ŽT2{ @l͏as]S >iԂie<Vg}3F5۝_A?Z{npI[FU|}w+!N%Oiu#[5Nw\p͘{$V~0( ee&88v2A;zȎ~x xJy$i6J#i:iҨ1NqxRm3oCY8IW\ŋ9yX|QV%>۸GLn;o=bVvj&3]W0j]19KӮe:w; YGz+icyeB+iwޛvg;emVbKQ2l)Gac`hj)Tiؘ3-%IYgJ輊j/W}0Tݜ{E?1L3M=⎥J5BQ~!G->:bI)7agRn&KqibTr[F!0QcQy?^^Wuv-/Y*gi|O:TAQ٠ǾO}%q\4BnkљaVWgPnuű :;7E]hZnb ~/f C%FR`[vTL!d;}ZV@O6$a%rP~XcnTW~Ak IL7gjM{'0B {zoŝ76\*w1 b&ڳ5jr]0?LTSh[Ӵe\{oi8`@C2E"Ҽ(H&_\8Nn.'W̎5oģ.O 8Nƪ*"k!Ό!6霓#՝W2#&Qby%Q^B +3a{1leʒ@-$RT'P/_RZwR˞ ?fGxnj,[J?>\w׎^:1s5@Ј/cM!vJG,H<ՏΛ l!sXBg{{v2vՉ7Ůn煁P=BzKf14ɶswxQ9!40YӒÔLaf3(;l(U:ϟD^'5TK Y `R?7Ww%T]~<ߴBH„Uca_)VyCskFG=A<IzOXsqOW_\ՀB%s&=Cwu+&? lf|-[2gVhS!5}) F%+p{9dg2\TEU]㈮YTO_뚺AUۓ(ܚS ŎDT$[($v~اmҒ4-3ByvY"J;z}vC]˪6"OĪg+mV)o6mdg\N ªm]b^ѐ~~g۬u O:&9tc,l:aY@4Te^2mHyDX̣)?ᨁp>IԏC̭NGgh(~'arX6EˤQiB>'/Dk"(Z_3ۣ3o/3^jo`ϒx#7`a s@/=[<:!Z.yBۦy *Hlw4tɀ$;BCyٌ/@zLG{u~PsWqߍbܭ(kgX<,Κ*MT࿸_\pe&wX;:?̝?Yf+ŕ:W)& C׏ou a'hgO!IBF.39`v^^",v13cUp%BԺDfpVL>RӅ{RaI#.NtƸ UA憸n- v\\xڣvS鎇)C_)\+4 wIYlkFs%G+|7-`*`:8P}zZ fd"Ph (>V:#q5M,H%UƼM S%4f&D˾0 vw:T¶V|0_0KW.GY䔨ݏ~V |eE+^,QɿSwtRKEs/-Zvcɐ+UŜ+]wk1vq[2zcIEn2Wsn(u:U.(ZpE*Sb(\q4>FZՒ{ts:*ˋ5g/֨l(~O(":НHY]{)`⍕9ygWb]cB?SYGuTWRIl~ ÒQ}xؿMx9D]2ep ĉ& Cr+aYJZS-2_qzK6l4R>A=TF9^9D*cpEFB`ieynJvj f6d!#T+<(vUPQ18*#ΆtuUDIQE7,?ulbwmPIg q[YYfIaqrD+o Mzio`0T]޺}C uCK̄ R|`SAd`=4]Ū(dLD\ eqdqm*(@au}?p8n YfṾniUQ~5?DL)|V^QyD869uGWYb<^R-X}x$OElewtwѨ_ yC53K28bh .sR"O ƩDxCwM,;\KL%kUuG5ZY%30Vɥc̽TGc#YÛp b;)oL3T0kO'3MP8?b_~7'HgسR^/Rʰ3_9M;3M5MvVNW_@բEF6Uyj{NJ4Rߓr%{P,Jɯux@D ) qӨԺ[]4'T;Beq= dn&+-Vx+;bKWUUaNglpS{L{lKR·np*1ê8 Y-Bz{sr"D/g*d"EX^rd47X´]㍡ e=a1ٻ ]I{1쁘$[fi)e>p^RcIi#- jK.3.q8[/~m?1ի,Vxco$k-fĀTACZ-Js $L>^Tpe0~hS w?4|l2R*Î|B#CUڲe US`p%"9K8si*s$@5~ˑE@`U{5mJ{ }E)&H_JDZ].ZѨ "D_e hKFA{[A:Vũ Sf/UƢ[1Po\]:bW@gj6~yق-EW\rX(ub}S9bj~Gឍ ilgc&Y^2i+&/rPȓ?tr7 t;> ,\F/ocq@!3-7=t芸0!4'5rb*RK[(:PR8[F1]9')J ك0Y P?F+]4~nU`F^gWC,nV3؊0]IL}mO5,ef8b~6P\k %A&ƴo{,1 ӼZĭDS~8X4KƊ&PAa{JW1NqG2EJ{ѕJu"D+Pڏ7f/*(7w#['_*5;SRq;d(T!bޔW(\ " B.K.a$ԭ\/sWUTnя^U^~_E"0 T²A1_,*t*,*X#|W{:[בzHMg"";ۣv4Ʒ X=LI4,p)ʦ\3C@L*J7{n~(V3`DH;1:iw8rppO#O3;Yr׍/Z,3;iEFKa ޔH.oQ<:R,YjvY9eF.}~; {}}{vL1[{^̜1Yt~}uxnZAD]g bswY6{Ky~{͢yG=8c {Klp>GDŽvc{u#Z:aK|x׽b V4:ngZ1@NwmxJBHfd(ډei_x{9ӰZg4pP~ l~k[˟Yfk;M;%h'I:H3z |o$ 64) |;wXZ&0d~9v=%(Wx\NӺk೭Q<ކF`.hJ~ 1 qs00m]uyZ}5s?鵩 M_Vhjik\il Aȹnf4 ɨuV>n;)rǠgyV=w[:^ J@z;x,ˆ_}rz>{W|ȷtb Wmt&l :#(+\K'["4*b\BlEq9i0E9gNNҲܛW"O^ds^?*|ݟW/ 5kzoxe:{/wbIiMBqC+O@dOE2K%nAKFX~(Oݐf&H\z,ߑ3NHbOI&CiKΫI.ΐHc4?䜋 \:Wo$KKx qP?b.*SI&|",&ITX<,>po)=f\D0D1Qwx=Qp}3.mizwPH+OO"\RLe 0O{xFԞo i2(((;ؕ'Y)l^I&҄IT(X4yz @^. ,=M&*FxjLCnTS:- PHE=h'f!#N(+Q^zr!w!C<8 ,<Ĕ@^/,D H avCkw1pLBOIٮ9FI_c2>)_ZX$MW0:[gc &x`R~.%/E) #7Yx {oBCf+4%f:.y)f9.镲tV?\{$Q-?EJca;MLUIf}{Rcر _~fV4TVJ>_9pTO[[ON緞o==z63\LD/jb@UA?eF.h;+؅ Gh8P Z,wox $+*H0Wj)oH;wb=j~YZ3u]ꚪt\Y[m*g$أ"sހ_ɿ;kk_ d}кK1iD/w0=b4$yVf֝RAWJ ez%K~o?i18{Oے0mĦ8nEm2%# {aӫݕYdS~Vز HyJhنNu!B%a{0Vgẋ؊FKRsm %ʌ?A29Ojig| SݒUYojv'e:#;h+<kKΖ2EN>eifB&:ƿ^# gck-- !̝  ;Ir%XMϾJsc!OPžu*%3  .X 9ָM"Eq{Ƭ" 6o]>}"+my"x"/•#p\ˆrŮ4g'Ov`.ЕKA4[+MA3ZŤA[j5_We5%.&vl YĉGƗ}+v߀LU) 3'"E0RhJ°1'Fquqe)UݝVdLAVVwgK*rD _4_BiVjqe{!OD&97>2zǩGcD +93U#S;ȎwV$ +of铣# g5~cg{qp!nϟsxi%\fy<@:΢?9jm]b[X<{Ap 2dqM=w\0~ۚw]I 1gX1X6^[KM~$_*>704 kULfP9/ps1jǧ?u~; l*=ـS!Ǝas9 q=Δr& ^w[&Yf%'q7~) ڙgɰY~{^ mtf}ofVȺQ1D {pb7/|g{[4ޖ ,Pʸu/zHC]*ͯyjP:s8.}K}04{gw'E3%a.b?)P?p^='.8b;$ ;|1t;.,t +y?LS% PyE/U"x|- 8OzR, K)3̲ѝz)pVq jDAA)mGD>F>髂H#{O$vGkU1 ' °{4vgV j|7C!) QǛ>߳h.gr/zd#=X-'U,XَXwV(Vi<ϩ!{ֶ&/9]Kx=):lfW1xY rDtE_,0Žpfp5±RvwvTJ {Ch. Z֭p E/_a"(hS}p3I~j+ >ŨsP~@=×<,[-yvT{A{rUI@Q ?_zF۩l|NoBj0W 6|^9oYwJz2l&=guqn<6pavQC&Oe.A5Ruam3Ŷ#kt (Ek".P2XX_s믿{'Ɂ`X7N J`iul'P1}BF9oP6h`8+sV^c/gj;]oKY^/>s^u:,~ pw}܁38n+ _go;4x"4I:w>`\7|>ߒ!=ձu^(4ńa!⼘`$Wx $郎,@8iK&'83Q2Y!܌qӅ8x.*sPDk5kE8VE@Բ5^y>޸w3}:x*_+ sf[\nmA7$Iy73 UbХ% C޻pmvG#י|I/0ix>Uܛ;Rܛҿ8/ ^-It!{q~HJH/}> = Ai[*-r,B"D)"bh՘,pv]P%ῄ\gɰ^|wVq' 9j|J { ACtvPu_ʹ+//=ffi/&"t:\!HՒk-'ΩjJ>9/p#)t&4Ka3038:N"0qFM9UۯE`UtuM?otՠd{N#ֶB9zq~qPe*v#yʼnD$b?wzB4b3M.~2^-PfJ<2N|f3 ;%-b^й$$ɭPTk<3Aǧ^(؅÷!i&Q2Od2"!_Wk P %SO$N' #i,uI"r`v?b=$.s<> Y̼jE=a}ky܄Kp25NɖA:X69@˸cyMx$+Bm0x2w0'?O5UgoM7$:DdWeagxadqSd C*OЗ^Lc])w+4;Flc~i{xv|Htt!ee.NfY9JK@ҙ|}1o%89W!lJ*ͤ}#pzꕞ_iaQ{fNeX0T+=b@Y`B:av@mQÒV⊥r;"Js`IJnU{|Y^ʪ› I~aI'z3qp+;9fW%V7ZnV/bV(XBږEI,XIȽpNOSUUsk?׍.m'=GPrƍWR :Fēˆ+u 1ɥr҄xpIH }˞J߲2Pug>hb͉x;Կіn5-țLIʧ"`='fѹ퀼Hklqa;|z.{ f6`%ixqZ `^QFBoWV~LEt>aY^pb_/3`KFmk}/j#Ȳ̹lfΊ&-dŽ9z$|dX7wE胘ۨOĩnL>ќeIn\&&,DIMmmrVCa]2uHLdDPDH˔]]sDˬ"] HdEsI`dmt PyRwn["ߓ?Ds@s%0?3K*M[R[&"I ௕}o4}hO1^OKK`D[^⤜R-YV>LUmoP"/pW_R"oӡD`&&GR^2>3`‡]7O{K"]$C 8wL႐+p_ɑg3f@_!8&6 żA۸uUJ4ᧇq{Sj,N% I[2LaCQ2R,ax%(- 0@-oZe-0pnc(٦#aqѲ.nd{I~bS#Z؋ VO3 93W2GH"(4? |,Ґm>Nj6}^zO?XX\2BI&= tͅrh2d:zYyw6+\bj T~T܆,SD m/w0,3+cuwHP!6Itق% 0/ƮZ5w;Zj.JbRM '{Jf}Uz&Ѥï ˆ8C`qĘQR&+8ml`-}aȶSAR1rS#!W@ ~¶Wlt^@!" <Ex}a-}vna`5@Z1 P`5HZr"V_oLdFhH,W=-n@WŗjB?|ZH;ŃA. >>qbAjd@W TCVhi)u*qBSXz]|Ogbj8@oq^wtdK7OkHRTfqs+i4<#W9ĆyeU;*eg$li0+6N ^wnZWᔻry7mkZI3cCRˍWWroCNbxDy_.*eU!;t[{z/&Vn=ϔ/Ľz0xU/51VnduO %LoBV!IiuP!^^9;jkfX0[gV`pP&bonp$Ɠ&/UR0le`Qmk`KxӶ/i\6nf6. V1^aBqyc܂a)5'Ȇ9>؇=[9b2fSV6enjX #pRq?ۓoN$dˑHݱ ?"s_{KN M"k6(>cJ@J܂,>jG3ep#Y:0icչ$Bys' Z'@2O2SXj/4r;V)* lz/ɰ'h"y[+et^Ӝ8+)\3 Z Ճ?,kokv/,^5dSf&cE.'<0 :ֹܠzjq{9$Ixt>S:%=Xϥ$ ߊĪma[4q[OA&vĹMya-) 3۟OZ\TuVDj09/_pM`_ U_vяNaU(ǃ^DOH=* 40> 6k}/?}X0xvbśVOK1F~|zG 5a=&N][ܽtX^ǁ>4ڽP8ߧ8K.JeC7d^~VOv6f~s?Zw\~}fq?l>9UtygQ0A0# edt}S0XIP~im.ڱrm?Ny9C;x̍%ZM ]цnEmoZ ^2?xS{cq8Hq+fBR!b[ (o9J8 ?ېB #bE`GTi$ CK6dOz7/~9xK|o*lEDko4ӭ3?i)kd߯`/W^ BsF?d=s;pCwzrzo[F=?Ow+/5aXXOpx8U䜑p iƇ*&mVjH&;,N霞;Ѭ7h%ap\:"_72+X̐;434`#Jt EpV h-="?NІ9(}^[:Qn\ .]vAcfM`|T7An9°&}O$(DܓlZY'*6yװ·/g^R\/撼|r `m!/ 'x>CWyQsV`—$KQ;|!;C{F~v#zw/-