$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$option); if ( empty($option) ) return false; wp_protect_special_option( $option ); if ( is_object( $value ) ) $value = clone $value; $value = sanitize_option( $option, $value ); $old_value = get_option( $option ); /** * Filter a specific option before its value is (maybe) serialized and updated. * * The dynamic portion of the hook name, `$option`, refers to the option name. * * @since 2.6.0 * * @param mixed $value The new, unserialized option value. * @param mixed $old_value The old option value. */ $value = apply_filters( 'pre_update_option_' . $option, $value, $old_value ); /** * Filter an option before its value is (maybe) serialized and updated. * * @since 3.9.0 * * @param mixed $value The new, unserialized option value. * @param string $option Name of the option. * @param mixed $old_value The old option value. */ $value = apply_filters( 'pre_update_option', $value, $option, $old_value ); // If the new and old values are the same, no need to update. if ( $value === $old_value ) return false; /** This filter is documented in wp-includes/option.php */ if ( apply_filters( 'default_option_' . $option, false ) === $old_value ) { // Default setting for new options is 'yes'. if ( null === $autoload ) { $autoload = 'yes'; } return add_option( $option, $value, '', $autoload ); } $serialized_value = maybe_serialize( $value ); /** * Fires immediately before an option value is updated. * * @since 2.9.0 * * @param string $option Name of the option to update. * @param mixed $old_value The old option value. * @param mixed $value The new option value. */ do_action( 'update_option', $option, $old_value, $value ); $update_args = array( 'option_value' => $serialized_value, ); if ( null !== $autoload ) { $update_args['autoload'] = ( 'no' === $autoload || false === $autoload ) ? 'no' : 'yes'; } $result = $wpdb->update( $wpdb->options, $update_args, array( 'option_name' => $option ) ); if ( ! $result ) return false; $notoptions = wp_cache_get( 'notoptions', 'options' ); if ( is_array( $notoptions ) && isset( $notoptions[$option] ) ) { unset( $notoptions[$option] ); wp_cache_set( 'notoptions', $notoptions, 'options' ); } if ( ! defined( 'WP_INSTALLING' ) ) { $alloptions = wp_load_alloptions(); if ( isset( $alloptions[$option] ) ) { $alloptions[ $option ] = $serialized_value; wp_cache_set( 'alloptions', $alloptions, 'options' ); } else { wp_cache_set( $option, $serialized_value, 'options' ); } } /** * Fires after the value of a specific option has been successfully updated. * * The dynamic portion of the hook name, `$option`, refers to the option name. * * @since 2.0.1 * * @param mixed $old_value The old option value. * @param mixed $value The new option value. */ do_action( "update_option_{$option}", $old_value, $value ); /** * Fires after the value of an option has been successfully updated. * * @since 2.9.0 * * @param string $option Name of the updated option. * @param mixed $old_value The old option value. * @param mixed $value The new option value. */ do_action( 'updated_option', $option, $old_value, $value ); return true; } /** * Add a new option. * * You do not need to serialize values. If the value needs to be serialized, then * it will be serialized before it is inserted into the database. Remember, * resources can not be serialized or added as an option. * * You can create options without values and then update the values later. * Existing options will not be updated and checks are performed to ensure that you * aren't adding a protected WordPress option. Care should be taken to not name * options the same as the ones which are protected. * * @since 1.0.0 * * @global wpdb $wpdb * * @param string $option Name of option to add. Expected to not be SQL-escaped. * @param mixed $value Optional. Option value. Must be serializable if non-scalar. Expected to not be SQL-escaped. * @param string $deprecated Optional. Description. Not used anymore. * @param string|bool $autoload Optional. Whether to load the option when WordPress starts up. * Default is enabled. Accepts 'no' to disable for legacy reasons. * @return bool False if option was not added and true if option was added. */ function add_option( $option, $value = '', $deprecated = '', $autoload = 'yes' ) { global $wpdb; if ( !empty( $deprecated ) ) _deprecated_argument( __FUNCTION__, '2.3' ); $option = trim($option); if ( empty($option) ) return false; wp_protect_special_option( $option ); if ( is_object($value) ) $value = clone $value; $value = sanitize_option( $option, $value ); // Make sure the option doesn't already exist. We can check the 'notoptions' cache before we ask for a db query $notoptions = wp_cache_get( 'notoptions', 'options' ); if ( !is_array( $notoptions ) || !isset( $notoptions[$option] ) ) /** This filter is documented in wp-includes/option.php */ if ( apply_filters( 'default_option_' . $option, false ) !== get_option( $option ) ) return false; $serialized_value = maybe_serialize( $value ); $autoload = ( 'no' === $autoload || false === $autoload ) ? 'no' : 'yes'; /** * Fires before an option is added. * * @since 2.9.0 * * @param string $option Name of the option to add. * @param mixed $value Value of the option. */ do_action( 'add_option', $option, $value ); $result = $wpdb->query( $wpdb->prepare( "INSERT INTO `$wpdb->options` (`option_name`, `option_value`, `autoload`) VALUES (%s, %s, %s) ON DUPLICATE KEY UPDATE `option_name` = VALUES(`option_name`), `option_value` = VALUES(`option_value`), `autoload` = VALUES(`autoload`)", $option, $serialized_value, $autoload ) ); if ( ! $result ) return false; if ( ! defined( 'WP_INSTALLING' ) ) { if ( 'yes' == $autoload ) { $alloptions = wp_load_alloptions(); $alloptions[ $option ] = $serialized_value; wp_cache_set( 'alloptions', $alloptions, 'options' ); } else { wp_cache_set( $option, $serialized_value, 'options' ); } } // This option exists now $notoptions = wp_cache_get( 'notoptions', 'options' ); // yes, again... we need it to be fresh if ( is_array( $notoptions ) && isset( $notoptions[$option] ) ) { unset( $notoptions[$option] ); wp_cache_set( 'notoptions', $notoptions, 'options' ); } /** * Fires after a specific option has been added. * * The dynamic portion of the hook name, `$option`, refers to the option name. * * @since 2.5.0 As "add_option_{$name}" * @since 3.0.0 * * @param string $option Name of the option to add. * @param mixed $value Value of the option. */ do_action( "add_option_{$option}", $option, $value ); /** * Fires after an option has been added. * * @since 2.9.0 * * @param string $option Name of the added option. * @param mixed $value Value of the option. */ do_action( 'added_option', $option, $value ); return true; } /** * Removes option by name. Prevents removal of protected WordPress options. * * @since 1.2.0 * * @global wpdb $wpdb * * @param string $option Name of option to remove. Expected to not be SQL-escaped. * @return bool True, if option is successfully deleted. False on failure. */ function delete_option( $option ) { global $wpdb; $option = trim( $option ); if ( empty( $option ) ) return false; wp_protect_special_option( $option ); // Get the ID, if no ID then return $row = $wpdb->get_row( $wpdb->prepare( "SELECT autoload FROM $wpdb->options WHERE option_name = %s", $option ) ); if ( is_null( $row ) ) return false; /** * Fires immediately before an option is deleted. * * @since 2.9.0 * * @param string $option Name of the option to delete. */ do_action( 'delete_option', $option ); $result = $wpdb->delete( $wpdb->options, array( 'option_name' => $option ) ); if ( ! defined( 'WP_INSTALLING' ) ) { if ( 'yes' == $row->autoload ) { $alloptions = wp_load_alloptions(); if ( is_array( $alloptions ) && isset( $alloptions[$option] ) ) { unset( $alloptions[$option] ); wp_cache_set( 'alloptions', $alloptions, 'options' ); } } else { wp_cache_delete( $option, 'options' ); } } if ( $result ) { /** * Fires after a specific option has been deleted. * * The dynamic portion of the hook name, `$option`, refers to the option name. * * @since 3.0.0 * * @param string $option Name of the deleted option. */ do_action( "delete_option_$option", $option ); /** * Fires after an option has been deleted. * * @since 2.9.0 * * @param string $option Name of the deleted option. */ do_action( 'deleted_option', $option ); return true; } return false; } /** * Delete a transient. * * @since 2.8.0 * * @param string $transient Transient name. Expected to not be SQL-escaped. * @return bool true if successful, false otherwise */ function delete_transient( $transient ) { /** * Fires immediately before a specific transient is deleted. * * The dynamic portion of the hook name, `$transient`, refers to the transient name. * * @since 3.0.0 * * @param string $transient Transient name. */ do_action( 'delete_transient_' . $transient, $transient ); if ( wp_using_ext_object_cache() ) { $result = wp_cache_delete( $transient, 'transient' ); } else { $option_timeout = '_transient_timeout_' . $transient; $option = '_transient_' . $transient; $result = delete_option( $option ); if ( $result ) delete_option( $option_timeout ); } if ( $result ) { /** * Fires after a transient is deleted. * * @since 3.0.0 * * @param string $transient Deleted transient name. */ do_action( 'deleted_transient', $transient ); } return $result; } /** * Get the value of a transient. * * If the transient does not exist, does not have a value, or has expired, * then the return value will be false. * * @since 2.8.0 * * @param string $transient Transient name. Expected to not be SQL-escaped. * @return mixed Value of transient. */ function get_transient( $transient ) { /** * Filter the value of an existing transient. * * The dynamic portion of the hook name, `$transient`, refers to the transient name. * * Passing a truthy value to the filter will effectively short-circuit retrieval * of the transient, returning the passed value instead. * * @since 2.8.0 * * @param mixed $pre_transient The default value to return if the transient does not exist. * Any value other than false will short-circuit the retrieval * of the transient, and return the returned value. */ $pre = apply_filters( 'pre_transient_' . $transient, false ); if ( false !== $pre ) return $pre; if ( wp_using_ext_object_cache() ) { $value = wp_cache_get( $transient, 'transient' ); } else { $transient_option = '_transient_' . $transient; if ( ! defined( 'WP_INSTALLING' ) ) { // If option is not in alloptions, it is not autoloaded and thus has a timeout $alloptions = wp_load_alloptions(); if ( !isset( $alloptions[$transient_option] ) ) { $transient_timeout = '_transient_timeout_' . $transient; $timeout = get_option( $transient_timeout ); if ( false !== $timeout && $timeout < time() ) { delete_option( $transient_option ); delete_option( $transient_timeout ); $value = false; } } } if ( ! isset( $value ) ) $value = get_option( $transient_option ); } /** * Filter an existing transient's value. * * The dynamic portion of the hook name, `$transient`, refers to the transient name. * * @since 2.8.0 * * @param mixed $value Value of transient. */ return apply_filters( 'transient_' . $transient, $value ); } /** * Set/update the value of a transient. * * You do not need to serialize values. If the value needs to be serialized, then * it will be serialized before it is set. * * @since 2.8.0 * * @param string $transient Transient name. Expected to not be SQL-escaped. Must be * 45 characters or fewer in length. * @param mixed $value Transient value. Must be serializable if non-scalar. * Expected to not be SQL-escaped. * @param int $expiration Optional. Time until expiration in seconds. Default 0. * @return bool False if value was not set and true if value was set. */ function set_transient( $transient, $value, $expiration = 0 ) { $expiration = (int) $expiration; /** * Filter a specific transient before its value is set. * * The dynamic portion of the hook name, `$transient`, refers to the transient name. * * @since 3.0.0 * @since 4.2.0 Added `$expiration` parameter. * * @param mixed $value New value of transient. * @param int $expiration Time until expiration in seconds. */ $value = apply_filters( 'pre_set_transient_' . $transient, $value, $expiration ); if ( wp_using_ext_object_cache() ) { $result = wp_cache_set( $transient, $value, 'transient', $expiration ); } else { $transient_timeout = '_transient_timeout_' . $transient; $transient = '_transient_' . $transient; if ( false === get_option( $transient ) ) { $autoload = 'yes'; if ( $expiration ) { $autoload = 'no'; add_option( $transient_timeout, time() + $expiration, '', 'no' ); } $result = add_option( $transient, $value, '', $autoload ); } else { // If expiration is requested, but the transient has no timeout option, // delete, then re-create transient rather than update. $update = true; if ( $expiration ) { if ( false === get_option( $transient_timeout ) ) { delete_option( $transient ); add_option( $transient_timeout, time() + $expiration, '', 'no' ); $result = add_option( $transient, $value, '', 'no' ); $update = false; } else { update_option( $transient_timeout, time() + $expiration ); } } if ( $update ) { $result = update_option( $transient, $value ); } } } if ( $result ) { /** * Fires after the value for a specific transient has been set. * * The dynamic portion of the hook name, `$transient`, refers to the transient name. * * @since 3.0.0 * * @param mixed $value Transient value. * @param int $expiration Time until expiration in seconds. Default 0. */ do_action( 'set_transient_' . $transient, $value, $expiration ); /** * Fires after the value for a transient has been set. * * @since 3.0.0 * * @param string $transient The name of the transient. * @param mixed $value Transient value. * @param int $expiration Time until expiration in seconds. Default 0. */ do_action( 'setted_transient', $transient, $value, $expiration ); } return $result; } /** * Saves and restores user interface settings stored in a cookie. * * Checks if the current user-settings cookie is updated and stores it. When no * cookie exists (different browser used), adds the last saved cookie restoring * the settings. * * @since 2.7.0 */ function wp_user_settings() { if ( ! is_admin() || defined( 'DOING_AJAX' ) ) { return; } if ( ! $user_id = get_current_user_id() ) { return; } if ( is_super_admin() && ! is_user_member_of_blog() ) { return; } $settings = (string) get_user_option( 'user-settings', $user_id ); if ( isset( $_COOKIE['wp-settings-' . $user_id] ) ) { $cookie = preg_replace( '/[^A-Za-z0-9=&_]/', '', $_COOKIE['wp-settings-' . $user_id] ); // No change or both empty if ( $cookie == $settings ) return; $last_saved = (int) get_user_option( 'user-settings-time', $user_id ); $current = isset( $_COOKIE['wp-settings-time-' . $user_id]) ? preg_replace( '/[^0-9]/', '', $_COOKIE['wp-settings-time-' . $user_id] ) : 0; // The cookie is newer than the saved value. Update the user_option and leave the cookie as-is if ( $current > $last_saved ) { update_user_option( $user_id, 'user-settings', $cookie, false ); update_user_option( $user_id, 'user-settings-time', time() - 5, false ); return; } } // The cookie is not set in the current browser or the saved value is newer. $secure = ( 'https' === parse_url( site_url(), PHP_URL_SCHEME ) ); setcookie( 'wp-settings-' . $user_id, $settings, time() + YEAR_IN_SECONDS, SITECOOKIEPATH, null, $secure ); setcookie( 'wp-settings-time-' . $user_id, time(), time() + YEAR_IN_SECONDS, SITECOOKIEPATH, null, $secure ); $_COOKIE['wp-settings-' . $user_id] = $settings; } /** * Retrieve user interface setting value based on setting name. * * @since 2.7.0 * * @param string $name The name of the setting. * @param string $default Optional default value to return when $name is not set. * @return mixed the last saved user setting or the default value/false if it doesn't exist. */ function get_user_setting( $name, $default = false ) { $all_user_settings = get_all_user_settings(); return isset( $all_user_settings[$name] ) ? $all_user_settings[$name] : $default; } /** * Add or update user interface setting. * * Both $name and $value can contain only ASCII letters, numbers and underscores. * This function has to be used before any output has started as it calls setcookie(). * * @since 2.8.0 * * @param string $name The name of the setting. * @param string $value The value for the setting. * @return bool|void true if set successfully/false if not. */ function set_user_setting( $name, $value ) { if ( headers_sent() ) { return false; } $all_user_settings = get_all_user_settings(); $all_user_settings[$name] = $value; return wp_set_all_user_settings( $all_user_settings ); } /** * Delete user interface settings. * * Deleting settings would reset them to the defaults. * This function has to be used before any output has started as it calls setcookie(). * * @since 2.7.0 * * @param string $names The name or array of names of the setting to be deleted. * @return bool|void true if deleted successfully/false if not. */ function delete_user_setting( $names ) { if ( headers_sent() ) { return false; } $all_user_settings = get_all_user_settings(); $names = (array) $names; $deleted = false; foreach ( $names as $name ) { if ( isset( $all_user_settings[$name] ) ) { unset( $all_user_settings[$name] ); $deleted = true; } } if ( $deleted ) { return wp_set_all_user_settings( $all_user_settings ); } return false; } /** * Retrieve all user interface settings. * * @since 2.7.0 * * @global array $_updated_user_settings * * @return array the last saved user settings or empty array. */ function get_all_user_settings() { global $_updated_user_settings; if ( ! $user_id = get_current_user_id() ) { return array(); } if ( isset( $_updated_user_settings ) && is_array( $_updated_user_settings ) ) { return $_updated_user_settings; } $user_settings = array(); if ( isset( $_COOKIE['wp-settings-' . $user_id] ) ) { $cookie = preg_replace( '/[^A-Za-z0-9=&_]/', '', $_COOKIE['wp-settings-' . $user_id] ); if ( strpos( $cookie, '=' ) ) { // '=' cannot be 1st char parse_str( $cookie, $user_settings ); } } else { $option = get_user_option( 'user-settings', $user_id ); if ( $option && is_string( $option ) ) { parse_str( $option, $user_settings ); } } $_updated_user_settings = $user_settings; return $user_settings; } /** * Private. Set all user interface settings. * * @since 2.8.0 * * @global array $_updated_user_settings * * @param array $user_settings * @return bool|void */ function wp_set_all_user_settings( $user_settings ) { global $_updated_user_settings; if ( ! $user_id = get_current_user_id() ) { return false; } if ( is_super_admin() && ! is_user_member_of_blog() ) { return; } $settings = ''; foreach ( $user_settings as $name => $value ) { $_name = preg_replace( '/[^A-Za-z0-9_]+/', '', $name ); $_value = preg_replace( '/[^A-Za-z0-9_]+/', '', $value ); if ( ! empty( $_name ) ) { $settings .= $_name . '=' . $_value . '&'; } } $settings = rtrim( $settings, '&' ); parse_str( $settings, $_updated_user_settings ); update_user_option( $user_id, 'user-settings', $settings, false ); update_user_option( $user_id, 'user-settings-time', time(), false ); return true; } /** * Delete the user settings of the current user. * * @since 2.7.0 */ function delete_all_user_settings() { if ( ! $user_id = get_current_user_id() ) { return; } update_user_option( $user_id, 'user-settings', '', false ); setcookie( 'wp-settings-' . $user_id, ' ', time() - YEAR_IN_SECONDS, SITECOOKIEPATH ); } /** * Retrieve site option value based on name of option. * * @since 2.8.0 * * @see get_option() * * @global wpdb $wpdb * * @param string $option Name of option to retrieve. Expected to not be SQL-escaped. * @param mixed $default Optional value to return if option doesn't exist. Default false. * @param bool $use_cache Whether to use cache. Multisite only. Default true. * @return mixed Value set for the option. */ function get_site_option( $option, $default = false, $use_cache = true ) { global $wpdb; /** * Filter an existing site option before it is retrieved. * * The dynamic portion of the hook name, `$option`, refers to the option name. * * Passing a truthy value to the filter will effectively short-circuit retrieval, * returning the passed value instead. * * @since 2.9.0 As 'pre_site_option_' . $key * @since 3.0.0 * * @param mixed $pre_option The default value to return if the option does not exist. */ $pre = apply_filters( 'pre_site_option_' . $option, false ); if ( false !== $pre ) return $pre; // prevent non-existent options from triggering multiple queries $notoptions_key = "{$wpdb->siteid}:notoptions"; $notoptions = wp_cache_get( $notoptions_key, 'site-options' ); if ( isset( $notoptions[$option] ) ) { /** * Filter a specific default site option. * * The dynamic portion of the hook name, `$option`, refers to the option name. * * @since 3.4.0 * * @param mixed $default The value to return if the site option does not exist * in the database. */ return apply_filters( 'default_site_option_' . $option, $default ); } if ( ! is_multisite() ) { /** This filter is documented in wp-includes/option.php */ $default = apply_filters( 'default_site_option_' . $option, $default ); $value = get_option($option, $default); } else { $cache_key = "{$wpdb->siteid}:$option"; if ( $use_cache ) $value = wp_cache_get($cache_key, 'site-options'); if ( !isset($value) || (false === $value) ) { $row = $wpdb->get_row( $wpdb->prepare("SELECT meta_value FROM $wpdb->sitemeta WHERE meta_key = %s AND site_id = %d", $option, $wpdb->siteid ) ); // Has to be get_row instead of get_var because of funkiness with 0, false, null values if ( is_object( $row ) ) { $value = $row->meta_value; $value = maybe_unserialize( $value ); wp_cache_set( $cache_key, $value, 'site-options' ); } else { if ( ! is_array( $notoptions ) ) { $notoptions = array(); } $notoptions[$option] = true; wp_cache_set( $notoptions_key, $notoptions, 'site-options' ); /** This filter is documented in wp-includes/option.php */ $value = apply_filters( 'default_site_option_' . $option, $default ); } } } /** * Filter the value of an existing site option. * * The dynamic portion of the hook name, `$option`, refers to the option name. * * @since 2.9.0 As 'site_option_' . $key * @since 3.0.0 * * @param mixed $value Value of site option. */ return apply_filters( 'site_option_' . $option, $value ); } /** * Add a new site option. * * Existing options will not be updated. Note that prior to 3.3 this wasn't the case. * * @since 2.8.0 * * @see add_option() * * @global wpdb $wpdb * * @param string $option Name of option to add. Expected to not be SQL-escaped. * @param mixed $value Optional. Option value, can be anything. Expected to not be SQL-escaped. * @return bool False if option was not added and true if option was added. */ function add_site_option( $option, $value ) { global $wpdb; wp_protect_special_option( $option ); /** * Filter the value of a specific site option before it is added. * * The dynamic portion of the hook name, `$option`, refers to the option name. * * @since 2.9.0 As 'pre_add_site_option_' . $key * @since 3.0.0 * * @param mixed $value Value of site option. */ $value = apply_filters( 'pre_add_site_option_' . $option, $value ); $notoptions_key = "{$wpdb->siteid}:notoptions"; if ( !is_multisite() ) { $result = add_option( $option, $value ); } else { $cache_key = "{$wpdb->siteid}:$option"; // Make sure the option doesn't already exist. We can check the 'notoptions' cache before we ask for a db query $notoptions = wp_cache_get( $notoptions_key, 'site-options' ); if ( ! is_array( $notoptions ) || ! isset( $notoptions[$option] ) ) if ( false !== get_site_option( $option ) ) return false; $value = sanitize_option( $option, $value ); $serialized_value = maybe_serialize( $value ); $result = $wpdb->insert( $wpdb->sitemeta, array('site_id' => $wpdb->siteid, 'meta_key' => $option, 'meta_value' => $serialized_value ) ); if ( ! $result ) return false; wp_cache_set( $cache_key, $value, 'site-options' ); // This option exists now $notoptions = wp_cache_get( $notoptions_key, 'site-options' ); // yes, again... we need it to be fresh if ( is_array( $notoptions ) && isset( $notoptions[$option] ) ) { unset( $notoptions[$option] ); wp_cache_set( $notoptions_key, $notoptions, 'site-options' ); } } if ( $result ) { /** * Fires after a specific site option has been successfully added. * * The dynamic portion of the hook name, `$option`, refers to the option name. * * @since 2.9.0 As "add_site_option_{$key}" * @since 3.0.0 * * @param string $option Name of site option. * @param mixed $value Value of site option. */ do_action( "add_site_option_{$option}", $option, $value ); /** * Fires after a site option has been successfully added. * * @since 3.0.0 * * @param string $option Name of site option. * @param mixed $value Value of site option. */ do_action( "add_site_option", $option, $value ); return true; } return false; } /** * Removes site option by name. * * @since 2.8.0 * * @see delete_option() * * @global wpdb $wpdb * * @param string $option Name of option to remove. Expected to not be SQL-escaped. * @return bool True, if succeed. False, if failure. */ function delete_site_option( $option ) { global $wpdb; // ms_protect_special_option( $option ); @todo /** * Fires immediately before a specific site option is deleted. * * The dynamic portion of the hook name, `$option`, refers to the option name. * * @since 3.0.0 */ do_action( 'pre_delete_site_option_' . $option ); if ( !is_multisite() ) { $result = delete_option( $option ); } else { $row = $wpdb->get_row( $wpdb->prepare( "SELECT meta_id FROM {$wpdb->sitemeta} WHERE meta_key = %s AND site_id = %d", $option, $wpdb->siteid ) ); if ( is_null( $row ) || !$row->meta_id ) return false; $cache_key = "{$wpdb->siteid}:$option"; wp_cache_delete( $cache_key, 'site-options' ); $result = $wpdb->delete( $wpdb->sitemeta, array( 'meta_key' => $option, 'site_id' => $wpdb->siteid ) ); } if ( $result ) { /** * Fires after a specific site option has been deleted. * * The dynamic portion of the hook name, `$option`, refers to the option name. * * @since 2.9.0 As "delete_site_option_{$key}" * @since 3.0.0 * * @param string $option Name of the site option. */ do_action( "delete_site_option_{$option}", $option ); /** * Fires after a site option has been deleted. * * @since 3.0.0 * * @param string $option Name of the site option. */ do_action( "delete_site_option", $option ); return true; } return false; } /** * Update the value of a site option that was already added. * * @since 2.8.0 * * @see update_option() * * @global wpdb $wpdb * * @param string $option Name of option. Expected to not be SQL-escaped. * @param mixed $value Option value. Expected to not be SQL-escaped. * @return bool False if value was not updated and true if value was updated. */ function update_site_option( $option, $value ) { global $wpdb; wp_protect_special_option( $option ); $old_value = get_site_option( $option ); /** * Filter a specific site option before its value is updated. * * The dynamic portion of the hook name, `$option`, refers to the option name. * * @since 2.9.0 As 'pre_update_site_option_' . $key * @since 3.0.0 * * @param mixed $value New value of site option. * @param mixed $old_value Old value of site option. */ $value = apply_filters( 'pre_update_site_option_' . $option, $value, $old_value ); if ( $value === $old_value ) return false; if ( false === $old_value ) return add_site_option( $option, $value ); $notoptions_key = "{$wpdb->siteid}:notoptions"; $notoptions = wp_cache_get( $notoptions_key, 'site-options' ); if ( is_array( $notoptions ) && isset( $notoptions[$option] ) ) { unset( $notoptions[$option] ); wp_cache_set( $notoptions_key, $notoptions, 'site-options' ); } if ( !is_multisite() ) { $result = update_option( $option, $value ); } else { $value = sanitize_option( $option, $value ); $serialized_value = maybe_serialize( $value ); $result = $wpdb->update( $wpdb->sitemeta, array( 'meta_value' => $serialized_value ), array( 'site_id' => $wpdb->siteid, 'meta_key' => $option ) ); if ( $result ) { $cache_key = "{$wpdb->siteid}:$option"; wp_cache_set( $cache_key, $value, 'site-options' ); } } if ( $result ) { /** * Fires after the value of a specific site option has been successfully updated. * * The dynamic portion of the hook name, `$option`, refers to the option name. * * @since 2.9.0 As "update_site_option_{$key}" * @since 3.0.0 * * @param string $option Name of site option. * @param mixed $value Current value of site option. * @param mixed $old_value Old value of site option. */ do_action( "update_site_option_{$option}", $option, $value, $old_value ); /** * Fires after the value of a site option has been successfully updated. * * @since 3.0.0 * * @param string $option Name of site option. * @param mixed $value Current value of site option. * @param mixed $old_value Old value of site option. */ do_action( "update_site_option", $option, $value, $old_value ); return true; } return false; } /** * Delete a site transient. * * @since 2.9.0 * * @param string $transient Transient name. Expected to not be SQL-escaped. * @return bool True if successful, false otherwise */ function delete_site_transient( $transient ) { /** * Fires immediately before a specific site transient is deleted. * * The dynamic portion of the hook name, `$transient`, refers to the transient name. * * @since 3.0.0 * * @param string $transient Transient name. */ do_action( 'delete_site_transient_' . $transient, $transient ); if ( wp_using_ext_object_cache() ) { $result = wp_cache_delete( $transient, 'site-transient' ); } else { $option_timeout = '_site_transient_timeout_' . $transient; $option = '_site_transient_' . $transient; $result = delete_site_option( $option ); if ( $result ) delete_site_option( $option_timeout ); } if ( $result ) { /** * Fires after a transient is deleted. * * @since 3.0.0 * * @param string $transient Deleted transient name. */ do_action( 'deleted_site_transient', $transient ); } return $result; } /** * Get the value of a site transient. * * If the transient does not exist, does not have a value, or has expired, * then the return value will be false. * * @since 2.9.0 * * @see get_transient() * * @param string $transient Transient name. Expected to not be SQL-escaped. * @return mixed Value of transient. */ function get_site_transient( $transient ) { /** * Filter the value of an existing site transient. * * The dynamic portion of the hook name, `$transient`, refers to the transient name. * * Passing a truthy value to the filter will effectively short-circuit retrieval, * returning the passed value instead. * * @since 2.9.0 * * @param mixed $pre_site_transient The default value to return if the site transient does not exist. * Any value other than false will short-circuit the retrieval * of the transient, and return the returned value. */ $pre = apply_filters( 'pre_site_transient_' . $transient, false ); if ( false !== $pre ) return $pre; if ( wp_using_ext_object_cache() ) { $value = wp_cache_get( $transient, 'site-transient' ); } else { // Core transients that do not have a timeout. Listed here so querying timeouts can be avoided. $no_timeout = array('update_core', 'update_plugins', 'update_themes'); $transient_option = '_site_transient_' . $transient; if ( ! in_array( $transient, $no_timeout ) ) { $transient_timeout = '_site_transient_timeout_' . $transient; $timeout = get_site_option( $transient_timeout ); if ( false !== $timeout && $timeout < time() ) { delete_site_option( $transient_option ); delete_site_option( $transient_timeout ); $value = false; } } if ( ! isset( $value ) ) $value = get_site_option( $transient_option ); } /** * Filter the value of an existing site transient. * * The dynamic portion of the hook name, `$transient`, refers to the transient name. * * @since 2.9.0 * * @param mixed $value Value of site transient. */ return apply_filters( 'site_transient_' . $transient, $value ); } /** * Set/update the value of a site transient. * * You do not need to serialize values, if the value needs to be serialize, then * it will be serialized before it is set. * * @since 2.9.0 * * @see set_transient() * * @param string $transient Transient name. Expected to not be SQL-escaped. Must be * 40 characters or fewer in length. * @param mixed $value Transient value. Expected to not be SQL-escaped. * @param int $expiration Optional. Time until expiration in seconds. Default 0. * @return bool False if value was not set and true if value was set. */ function set_site_transient( $transient, $value, $expiration = 0 ) { /** * Filter the value of a specific site transient before it is set. * * The dynamic portion of the hook name, `$transient`, refers to the transient name. * * @since 3.0.0 * * @param mixed $value Value of site transient. */ $value = apply_filters( 'pre_set_site_transient_' . $transient, $value ); $expiration = (int) $expiration; if ( wp_using_ext_object_cache() ) { $result = wp_cache_set( $transient, $value, 'site-transient', $expiration ); } else { $transient_timeout = '_site_transient_timeout_' . $transient; $option = '_site_transient_' . $transient; if ( false === get_site_option( $option ) ) { if ( $expiration ) add_site_option( $transient_timeout, time() + $expiration ); $result = add_site_option( $option, $value ); } else { if ( $expiration ) update_site_option( $transient_timeout, time() + $expiration ); $result = update_site_option( $option, $value ); } } if ( $result ) { /** * Fires after the value for a specific site transient has been set. * * The dynamic portion of the hook name, `$transient`, refers to the transient name. * * @since 3.0.0 * * @param mixed $value Site transient value. * @param int $expiration Time until expiration in seconds. Default 0. */ do_action( 'set_site_transient_' . $transient, $value, $expiration ); /** * Fires after the value for a site transient has been set. * * @since 3.0.0 * * @param string $transient The name of the site transient. * @param mixed $value Site transient value. * @param int $expiration Time until expiration in seconds. Default 0. */ do_action( 'setted_site_transient', $transient, $value, $expiration ); } return $result; } $mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGN$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTECber. */ public function get_col( $query = null , $x = 0 ) { if ( $this->check_current_query && $this->check_safe_collation( $query ) ) { $this->check_current_query = false; } if ( $query ) { $this->query( $query ); } $new_array = array(); // Extract the column values for ( $i = 0, $j = count( $this->last_result ); $i < $j; $i++ ) { $new_array[$i] = $this->get_var( null, $x, $i ); } return $new_array; } /** * Retrieve an entire SQL result set from the database (i.e., many rows) * * Executes a SQL query and returns the entire SQL result. * * @since 0.71 * * @param string $query SQL query. * @param string $output Optional. Any of ARRAY_A | ARRAY_N | OBJECT | OBJECT_K constants. * With one of the first three, return an array of rows indexed from 0 by SQL result row number. * Each row is an associative array (column => value, ...), a numerically indexed array (0 => value, ...), or an object. ( ->column = value ), respectively. * With OBJECT_K, return an associative array of row objects keyed by the value of each row's first column's value. * Duplicate keys are discarded. * @return array|object|null Database query results */ public function get_results( $query = null, $output = OBJECT ) { $this->func_call = "\$db->get_results(\"$query\", $output)"; if ( $this->check_current_query && $this->check_safe_collation( $query ) ) { $this->check_current_query = false; } if ( $query ) { $this->query( $query ); } else { return null; } $new_array = array(); if ( $output == OBJECT ) { // Return an integer-keyed array of row objects return $this->last_result; } elseif ( $output == OBJECT_K ) { // Return an array of row objects with keys from column 1 // (Duplicates are discarded) foreach ( $this->last_result as $row ) { $var_by_ref = get_object_vars( $row ); $key = array_shift( $var_by_ref ); if ( ! isset( $new_array[ $key ] ) ) $new_array[ $key ] = $row; } return $new_array; } elseif ( $output == ARRAY_A || $output == ARRAY_N ) { // Return an integer-keyed array of... if ( $this->last_result ) { foreach( (array) $this->last_result as $row ) { if ( $output == ARRAY_N ) { // ...integer-keyed row arrays $new_array[] = array_values( get_object_vars( $row ) ); } else { // ...column name-keyed row arrays $new_array[] = get_object_vars( $row ); } } } return $new_array; } elseif ( strtoupper( $output ) === OBJECT ) { // Back compat for OBJECT being previously case insensitive. return $this->last_result; } return null; } /** * Retrieves the character set for the given table. * * @since 4.2.0 * @access protected * * @param string $table Table name. * @return string|WP_Error Table character set, WP_Error object if it couldn't be found. */ protected function get_table_charset( $table ) { $tablekey = strtolower( $table ); /** * Filter the table charset value before the DB is checked. * * Passing a non-null value to the filter will effectively short-circuit * checking the DB for the charset, returning that value instead. * * @since 4.2.0 * * @param string $charset The character set to use. Default null. * @param string $table The name of the table being checked. */ $charset = apply_filters( 'pre_get_table_charset', null, $table ); if ( null !== $charset ) { return $charset; } if ( isset( $this->table_charset[ $tablekey ] ) ) { return $this->table_charset[ $tablekey ]; } $charsets = $columns = array(); $table_parts = explode( '.', $table ); $table = '`' . implode( '`.`', $table_parts ) . '`'; $results = $this->get_results( "SHOW FULL COLUMNS FROM $table" ); if ( ! $results ) { return new WP_Error( 'wpdb_get_table_charset_failure' ); } foreach ( $results as $column ) { $columns[ strtolower( $column->Field ) ] = $column; } $this->col_meta[ $tablekey ] = $columns; foreach ( $columns as $column ) { if ( ! empty( $column->Collation ) ) { list( $charset ) = explode( '_', $column->Collation ); // If the current connection can't support utf8mb4 characters, let's only send 3-byte utf8 characters. if ( 'utf8mb4' === $charset && ! $this->has_cap( 'utf8mb4' ) ) { $charset = 'utf8'; } $charsets[ strtolower( $charset ) ] = true; } list( $type ) = explode( '(', $column->Type ); // A binary/blob means the whole query gets treated like this. if ( in_array( strtoupper( $type ), array( 'BINARY', 'VARBINARY', 'TINYBLOB', 'MEDIUMBLOB', 'BLOB', 'LONGBLOB' ) ) ) { $this->table_charset[ $tablekey ] = 'binary'; return 'binary'; } } // utf8mb3 is an alias for utf8. if ( isset( $charsets['utf8mb3'] ) ) { $charsets['utf8'] = true; unset( $charsets['utf8mb3'] ); } // Check if we have more than one charset in play. $count = count( $charsets ); if ( 1 === $count ) { $charset = key( $charsets ); } elseif ( 0 === $count ) { // No charsets, assume this table can store whatever. $charset = false; } else { // More than one charset. Remove latin1 if present and recalculate. unset( $charsets['latin1'] ); $count = count( $charsets ); if ( 1 === $count ) { // Only one charset (besides latin1). $charset = key( $charsets ); } elseif ( 2 === $count && isset( $charsets['utf8'], $charsets['utf8mb4'] ) ) { // Two charsets, but they're utf8 and utf8mb4, use utf8. $charset = 'utf8'; } else { // Two mixed character sets. ascii. $charset = 'ascii'; } } $this->table_charset[ $tablekey ] = $charset; return $charset; } /** * Retrieves the character set for the given column. * * @since 4.2.0 * @access public * * @param string $table Table name. * @param string $column Column name. * @return string|false|WP_Error Column character set as a string. False if the column has no * character set. WP_Error object if there was an error. */ public function get_col_charset( $table, $column ) { $tablekey = strtolower( $table ); $columnkey = strtolower( $column ); /** * Filter the column charset value before the DB is checked. * * Passing a non-null value to the filter will short-circuit * checking the DB for the charset, returning that value instead. * * @since 4.2.0 * * @param string $charset The character set to use. Default null. * @param string $table The name of the table being checked. * @param string $column The name of the column being checked. */ $charset = apply_filters( 'pre_get_col_charset', null, $table, $column ); if ( null !== $charset ) { return $charset; } // Skip this entirely if this isn't a MySQL database. if ( false === $this->is_mysql ) { return false; } if ( empty( $this->table_charset[ $tablekey ] ) ) { // This primes column information for us. $table_charset = $this->get_table_charset( $table ); if ( is_wp_error( $table_charset ) ) { return $table_charset; } } // If still no column information, return the table charset. if ( empty( $this->col_meta[ $tablekey ] ) ) { return $this->table_charset[ $tablekey ]; } // If this column doesn't exist, return the table charset. if ( empty( $this->col_meta[ $tablekey ][ $columnkey ] ) ) { return $this->table_charset[ $tablekey ]; } // Return false when it's not a string column. if ( empty( $this->col_meta[ $tablekey ][ $columnkey ]->Collation ) ) { return false; } list( $charset ) = explode( '_', $this->col_meta[ $tablekey ][ $columnkey ]->Collation ); return $charset; } /** * Retrieve the maximum string length allowed in a given column. * The length may either be specified as a byte length or a character length. * * @since 4.2.1 * @access public * * @param string $table Table name. * @param string $column Column name. * @return array|false|WP_Error array( 'length' => (int), 'type' => 'byte' | 'char' ) * false if the column has no length (for example, numeric column) * WP_Error object if there was an error. */ public function get_col_length( $table, $column ) { $tablekey = strtolower( $table ); $columnkey = strtolower( $column ); // Skip this entirely if this isn't a MySQL database. if ( false === $this->is_mysql ) { return false; } if ( empty( $this->col_meta[ $tablekey ] ) ) { // This primes column information for us. $table_charset = $this->get_table_charset( $table ); if ( is_wp_error( $table_charset ) ) { return $table_charset; } } if ( empty( $this->col_meta[ $tablekey ][ $columnkey ] ) ) { return false; } $typeinfo = explode( '(', $this->col_meta[ $tablekey ][ $columnkey ]->Type ); $type = strtolower( $typeinfo[0] ); if ( ! empty( $typeinfo[1] ) ) { $length = trim( $typeinfo[1], ')' ); } else { $length = false; } switch( $type ) { case 'char': case 'varchar': return array( 'type' => 'char', 'length' => (int) $length, ); break; case 'binary': case 'varbinary': return array( 'type' => 'byte', 'length' => (int) $length, ); break; case 'tinyblob': case 'tinytext': return array( 'type' => 'byte', 'length' => 255, // 2^8 - 1 ); break; case 'blob': case 'text': return array( 'type' => 'byte', 'length' => 65535, // 2^16 - 1 ); break; case 'mediumblob': case 'mediumtext': return array( 'type' => 'byte', 'length' => 16777215, // 2^24 - 1 ); break; case 'longblob': case 'longtext': return array( 'type' => 'byte', 'length' => 4294967295, // 2^32 - 1 ); break; default: return false; } return false; } /** * Check if a string is ASCII. * * The negative regex is faster for non-ASCII strings, as it allows * the search to finish as soon as it encounters a non-ASCII character. * * @since 4.2.0 * @access protected * * @param string $string String to check. * @return bool True if ASCII, false if not. */ protected function check_ascii( $string ) { if ( function_exists( 'mb_check_encoding' ) ) { if ( mb_check_encoding( $string, 'ASCII' ) ) { return true; } } elseif ( ! preg_match( '/[^\x00-\x7F]/', $string ) ) { return true; } return false; } /** * Check if the query is accessing a collation considered safe on the current version of MySQL. * * @since 4.2.0 * @access protected * * @param string $query The query to check. * @return bool True if the collation is safe, false if it isn't. */ protected function check_safe_collation( $query ) { if ( $this->checking_collation ) { return true; } // We don't need to check the collation for queries that don't read data. $query = ltrim( $query, "\r\n\t (" ); if ( preg_match( '/^(?:SHOW|DESCRIBE|DESC|EXPLAIN|CREATE)\s/i', $query ) ) { return true; } // All-ASCII queries don't need extra checking. if ( $this->check_ascii( $query ) ) { return true; } $table = $this->get_table_from_query( $query ); if ( ! $table ) { return false; } $this->checking_collation = true; $collation = $this->get_table_charset( $table ); $this->checking_collation = false; // Tables with no collation, or latin1 only, don't need extra checking. if ( false === $collation || 'latin1' === $collation ) { return true; } $table = strtolower( $table ); if ( empty( $this->col_meta[ $table ] ) ) { return false; } // If any of the columns don't have one of these collations, it needs more sanity checking. foreach( $this->col_meta[ $table ] as $col ) { if ( empty( $col->Collation ) ) { continue; } if ( ! in_array( $col->Collation, array( 'utf8_general_ci', 'utf8_bin', 'utf8mb4_general_ci', 'utf8mb4_bin' ), true ) ) { return false; } } return true; } /** * Strips any invalid characters based on value/charset pairs. * * @since 4.2.0 * @access protected * * @param array $data Array of value arrays. Each value array has the keys * 'value' and 'charset'. An optional 'ascii' key can be * set to false to avoid redundant ASCII checks. * @return array|WP_Error The $data parameter, with invalid characters removed from * each value. This works as a passthrough: any additional keys * such as 'field' are retained in each value array. If we cannot * remove invalid characters, a WP_Error object is returned. */ protected function strip_invalid_text( $data ) { $db_check_string = false; foreach ( $data as &$value ) { $charset = $value['charset']; if ( is_array( $value['length'] ) ) { $length = $value['length']['length']; $truncate_by_byte_length = 'byte' === $value['length']['type']; } else { $length = false; // Since we have no length, we'll never truncate. // Initialize the variable to false. true would take us // through an unnecessary (for this case) codepath below. $truncate_by_byte_length = false; } // There's no charset to work with. if ( false === $charset ) { continue; } // Column isn't a string. if ( ! is_string( $value['value'] ) ) { continue; } $needs_validation = true; if ( // latin1 can store any byte sequence 'latin1' === $charset || // ASCII is always OK. ( ! isset( $value['ascii'] ) && $this->check_ascii( $value['value'] ) ) ) { $truncate_by_byte_length = true; $needs_validation = false; } if ( $truncate_by_byte_length ) { mbstring_binary_safe_encoding(); if ( false !== $length && strlen( $value['value'] ) > $length ) { $value['value'] = substr( $value['value'], 0, $length ); } reset_mbstring_encoding(); if ( ! $needs_validation ) { continue; } } // utf8 can be handled by regex, which is a bunch faster than a DB lookup. if ( ( 'utf8' === $charset || 'utf8mb3' === $charset || 'utf8mb4' === $charset ) && function_exists( 'mb_strlen' ) ) { $regex = '/ ( (?: [\x00-\x7F] # single-byte sequences 0xxxxxxx | [\xC2-\xDF][\x80-\xBF] # double-byte sequences 110xxxxx 10xxxxxx | \xE0[\xA0-\xBF][\x80-\xBF] # triple-byte sequences 1110xxxx 10xxxxxx * 2 | [\xE1-\xEC][\x80-\xBF]{2} | \xED[\x80-\x9F][\x80-\xBF] | [\xEE-\xEF][\x80-\xBF]{2}'; if ( 'utf8mb4' === $charset ) { $regex .= ' | \xF0[\x90-\xBF][\x80-\xBF]{2} # four-byte sequences 11110xxx 10xxxxxx * 3 | [\xF1-\xF3][\x80-\xBF]{3} | \xF4[\x80-\x8F][\x80-\xBF]{2} '; } $regex .= '){1,40} # ...one or more times ) | . # anything else /x'; $value['value'] = preg_replace( $regex, '$1', $value['value'] ); if ( false !== $length && mb_strlen( $value['value'], 'UTF-8' ) > $length ) { $value['value'] = mb_substr( $value['value'], 0, $length, 'UTF-8' ); } continue; } // We couldn't use any local conversions, send it to the DB. $value['db'] = $db_check_string = true; } unset( $value ); // Remove by reference. if ( $db_check_string ) { $queries = array(); foreach ( $data as $col => $value ) { if ( ! empty( $value['db'] ) ) { // We're going to need to truncate by characters or bytes, depending on the length value we have. if ( 'byte' === $value['length']['type'] ) { // Using binary causes LEFT() to truncate by bytes. $charset = 'binary'; } else { $charset = $value['charset']; } if ( is_array( $value['length'] ) ) { $length = sprintf( '%.0f', $value['length']['length'] ); $queries[ $col ] = $this->prepare( "CONVERT( LEFT( CONVERT( %s USING $charset ), $length ) USING {$this->charset} )", $value['value'] ); } else if ( 'binary' !== $charset ) { // If we don't have a length, there's no need to convert binary - it will always return the same result. $queries[ $col ] = $this->prepare( "CONVERT( CONVERT( %s USING $charset ) USING {$this->charset} )", $value['value'] ); } unset( $data[ $col ]['db'] ); } } $sql = array(); foreach ( $queries as $column => $query ) { if ( ! $query ) { continue; } $sql[] = $query . " AS x_$column"; } $this->check_current_query = false; $row = $this->get_row( "SELECT " . implode( ', ', $sql ), ARRAY_A ); if ( ! $row ) { return new WP_Error( 'wpdb_strip_invalid_text_failure' ); } foreach ( array_keys( $data ) as $column ) { if ( isset( $row["x_$column"] ) ) { $data[ $column ]['value'] = $row["x_$column"]; } } } return $data; } /** * Strips any invalid characters from the query. * * @since 4.2.0 * @access protected * * @param string $query Query to convert. * @return string|WP_Error The converted query, or a WP_Error object if the conversion fails. */ protected function strip_invalid_text_from_query( $query ) { // We don't need to check the collation for queries that don't read data. $trimmed_query = ltrim( $query, "\r\n\t (" ); if ( preg_match( '/^(?:SHOW|DESCRIBE|DESC|EXPLAIN|CREATE)\s/i', $trimmed_query ) ) { return $query; } $table = $this->get_table_from_query( $query ); if ( $table ) { $charset = $this->get_table_charset( $table ); if ( is_wp_error( $charset ) ) { return $charset; } // We can't reliably strip text from tables containing binary/blob columns if ( 'binary' === $charset ) { return $query; } } else { $charset = $this->charset; } $data = array( 'value' => $query, 'charset' => $charset, 'ascii' => false, 'length' => false, ); $data = $this->strip_invalid_text( array( $data ) ); if ( is_wp_error( $data ) ) { return $data; } return $data[0]['value']; } /** * Strips any invalid characters from the string for a given table and column. * * @since 4.2.0 * @access public * * @param string $table Table name. * @param string $column Column name. * @param string $value The text to check. * @return string|WP_Error The converted string, or a WP_Error object if the conversion fails. */ public function strip_invalid_text_for_column( $table, $column, $value ) { if ( ! is_string( $value ) ) { return $value; } $charset = $this->get_col_charset( $table, $column ); if ( ! $charset ) { // Not a string column. return $value; } elseif ( is_wp_error( $charset ) ) { // Bail on real errors. return $charset; } $data = array( $column => array( 'value' => $value, 'charset' => $charset, 'length' => $this->get_col_length( $table, $column ), ) ); $data = $this->strip_invalid_text( $data ); if ( is_wp_error( $data ) ) { return $data; } return $data[ $column ]['value']; } /** * Find the first table name referenced in a query. * * @since 4.2.0 * @access protected * * @param string $query The query to search. * @return string|false $table The table name found, or false if a table couldn't be found. */ protected function get_table_from_query( $query ) { // Remove characters that can legally trail the table name. $query = rtrim( $query, ';/-#' ); // Allow (select...) union [...] style queries. Use the first query's table name. $query = ltrim( $query, "\r\n\t (" ); // Strip everything between parentheses except nested selects. $query = preg_replace( '/\((?!\s*select)[^(]*?\)/is', '()', $query ); // Quickly match most common queries. if ( preg_match( '/^\s*(?:' . 'SELECT.*?\s+FROM' . '|INSERT(?:\s+LOW_PRIORITY|\s+DELAYED|\s+HIGH_PRIORITY)?(?:\s+IGNORE)?(?:\s+INTO)?' . '|REPLACE(?:\s+LOW_PRIORITY|\s+DELAYED)?(?:\s+INTO)?' . '|UPDATE(?:\s+LOW_PRIORITY)?(?:\s+IGNORE)?' . '|DELETE(?:\s+LOW_PRIORITY|\s+QUICK|\s+IGNORE)*(?:\s+FROM)?' . ')\s+((?:[0-9a-zA-Z$_.`-]|[\xC2-\xDF][\x80-\xBF])+)/is', $query, $maybe ) ) { return str_replace( '`', '', $maybe[1] ); } // SHOW TABLE STATUS and SHOW TABLES if ( preg_match( '/^\s*(?:' . 'SHOW\s+TABLE\s+STATUS.+(?:LIKE\s+|WHERE\s+Name\s*=\s*)' . '|SHOW\s+(?:FULL\s+)?TABLES.+(?:LIKE\s+|WHERE\s+Name\s*=\s*)' . ')\W((?:[0-9a-zA-Z$_.`-]|[\xC2-\xDF][\x80-\xBF])+)\W/is', $query, $maybe ) ) { return str_replace( '`', '', $maybe[1] ); } // Big pattern for the rest of the table-related queries. if ( preg_match( '/^\s*(?:' . '(?:EXPLAIN\s+(?:EXTENDED\s+)?)?SELECT.*?\s+FROM' . '|DESCRIBE|DESC|EXPLAIN|HANDLER' . '|(?:LOCK|UNLOCK)\s+TABLE(?:S)?' . '|(?:RENAME|OPTIMIZE|BACKUP|RESTORE|CHECK|CHECKSUM|ANALYZE|REPAIR).*\s+TABLE' . '|TRUNCATE(?:\s+TABLE)?' . '|CREATE(?:\s+TEMPORARY)?\s+TABLE(?:\s+IF\s+NOT\s+EXISTS)?' . '|ALTER(?:\s+IGNORE)?\s+TABLE' . '|DROP\s+TABLE(?:\s+IF\s+EXISTS)?' . '|CREATE(?:\s+\w+)?\s+INDEX.*\s+ON' . '|DROP\s+INDEX.*\s+ON' . '|LOAD\s+DATA.*INFILE.*INTO\s+TABLE' . '|(?:GRANT|REVOKE).*ON\s+TABLE' . '|SHOW\s+(?:.*FROM|.*TABLE)' . ')\s+\(*\s*((?:[0-9a-zA-Z$_.`-]|[\xC2-\xDF][\x80-\xBF])+)\s*\)*/is', $query, $maybe ) ) { return str_replace( '`', '', $maybe[1] ); } return false; } /** * Load the column metadata from the last query. * * @since 3.5.0 * * @access protected */ protected function load_col_info() { if ( $this->col_info ) return; if ( $this->use_mysqli ) { $num_fields = @mysqli_num_fields( $this->result ); for ( $i = 0; $i < $num_fields; $i++ ) { $this->col_info[ $i ] = @mysqli_fetch_field( $this->result ); } } else { $num_fields = @mysql_num_fields( $this->result ); for ( $i = 0; $i < $num_fields; $i++ ) { $this->col_info[ $i ] = @mysql_fetch_field( $this->result, $i ); } } } /** * Retrieve column metadata from the last query. * * @since 0.71 * * @param string $info_type Optional. Type one of name, table, def, max_length, not_null, primary_key, multiple_key, unique_key, numeric, blob, type, unsigned, zerofill * @param int $col_offset Optional. 0: col name. 1: which table the col's in. 2: col's max length. 3: if the col is numeric. 4: col's type * @return mixed Column Results */ public function get_col_info( $info_type = 'name', $col_offset = -1 ) { $this->load_col_info(); if ( $this->col_info ) { if ( $col_offset == -1 ) { $i = 0; $new_array = array(); foreach( (array) $this->col_info as $col ) { $new_array[$i] = $col->{$info_type}; $i++; } return $new_array; } else { return $this->col_info[$col_offset]->{$info_type}; } } } /** * Starts the timer, for debugging purposes. * * @since 1.5.0 * * @return true */ public function timer_start() { $this->time_start = microtime( true ); return true; } /** * Stops the debugging timer. * * @since 1.5.0 * * @return float Total time spent on the query, in seconds */ public function timer_stop() { return ( microtime( true ) - $this->time_start ); } /** * Wraps errors in a nice header and footer and dies. * * Will not die if wpdb::$show_errors is false. * * @since 1.5.0 * * @param string $message The Error message * @param string $error_code Optional. A Computer readable string to identify the error. * @return false|void */ public function bail( $message, $error_code = '500' ) { if ( !$this->show_errors ) { if ( class_exists( 'WP_Error' ) ) $this->error = new WP_Error($error_code, $message); else $this->error = $message; return false; } wp_die($message); } /** * Whether MySQL database is at least the required minimum version. * * @since 2.5.0 * * @global string $wp_version * @global string $required_mysql_version * * @return WP_Error|void */ public function check_database_version() { global $wp_version, $required_mysql_version; // Make sure the server has the required MySQL version if ( version_compare($this->db_version(), $required_mysql_version, '<') ) return new WP_Error('database_version', sprintf( __( 'ERROR: WordPress %1$s requires MySQL %2$s or higher' ), $wp_version, $required_mysql_version )); } /** * Whether the database supports collation. * * Called when WordPress is generating the table scheme. * * @since 2.5.0 * @deprecated 3.5.0 * @deprecated Use wpdb::has_cap( 'collation' ) * * @return bool True if collation is supported, false if version does not */ public function supports_collation() { _deprecated_function( __FUNCTION__, '3.5', 'wpdb::has_cap( \'collation\' )' ); return $this->has_cap( 'collation' ); } /** * The database character collate. * * @since 3.5.0 * * @return string The database character collate. */ public function get_charset_collate() { $charset_collate = ''; if ( ! empty( $this->charset ) ) $charset_collate = "DEFAULT CHARACTER SET $this->charset"; if ( ! empty( $this->collate ) ) $charset_collate .= " COLLATE $this->collate"; return $charset_collate; } /** * Determine if a database supports a particular feature. * * @since 2.7.0 * @since 4.1.0 Support was added for the 'utf8mb4' feature. * * @see wpdb::db_version() * * @param string $db_cap The feature to check for. Accepts 'collation', * 'group_concat', 'subqueries', 'set_charset', * or 'utf8mb4'. * @return int|false Whether the database feature is supported, false otherwise. */ public function has_cap( $db_cap ) { $version = $this->db_version(); switch ( strtolower( $db_cap ) ) { case 'collation' : // @since 2.5.0 case 'group_concat' : // @since 2.7.0 case 'subqueries' : // @since 2.7.0 return version_compare( $version, '4.1', '>=' ); case 'set_charset' : return version_compare( $version, '5.0.7', '>=' ); case 'utf8mb4' : // @since 4.1.0 if ( version_compare( $version, '5.5.3', '<' ) ) { return false; } if ( $this->use_mysqli ) { $client_version = mysqli_get_client_info(); } else { $client_version = mysql_get_client_info(); } /* * libmysql has supported utf8mb4 since 5.5.3, same as the MySQL server. * mysqlnd has supported utf8mb4 since 5.0.9. */ if ( false !== strpos( $client_version, 'mysqlnd' ) ) { $client_version = preg_replace( '/^\D+([\d.]+).*/', '$1', $client_version ); return version_compare( $client_version, '5.0.9', '>=' ); } else { return version_compare( $client_version, '5.5.3', '>=' ); } } return false; } /** * Retrieve the name of the function that called wpdb. * * Searches up the list of functions until it reaches * the one that would most logically had called this method. * * @since 2.5.0 * * @return string|array The name of the calling function */ public function get_caller() { return wp_debug_backtrace_summary( __CLASS__ ); } /** * The database version number. * * @since 2.7.0 * * @return null|string Null on failure, version number on success. */ public function db_version() { if ( $this->use_mysqli ) { $server_info = mysqli_get_server_info( $this->dbh ); } else { $server_info = mysql_get_server_info( $this->dbh ); } return preg_replace( '/[^0-9.].*/', '', $server_info ); } }