diff --git a/.github/workflows/build-dev-artifacts.yml b/.github/workflows/build-dev-artifacts.yml
index 3165840e..ff9e81db 100755
--- a/.github/workflows/build-dev-artifacts.yml
+++ b/.github/workflows/build-dev-artifacts.yml
@@ -26,7 +26,8 @@ jobs:
- name: Create zip
run: |
npm ci
- npm run build
+ npm run build
+ npm version patch --no-git-tag-version
CURRENT_VERSION=$(node -p -e "require('./package.json').version")
COMMIT_HASH=$(git rev-parse --short HEAD)
DEV_VERSION="${CURRENT_VERSION}-dev.${COMMIT_HASH}"
diff --git a/css/feedzy-rss-feed-import.css b/css/feedzy-rss-feed-import.css
index d2c83da1..75daee62 100644
--- a/css/feedzy-rss-feed-import.css
+++ b/css/feedzy-rss-feed-import.css
@@ -8,7 +8,7 @@
* Author: Themeisle
*/
-#feedzy_import_feeds{
+#feedzy_import_feeds {
background: transparent;
border: 0;
box-shadow: none;
@@ -18,49 +18,62 @@
padding-right: 12px;
box-sizing: border-box;
}
-#feedzy_import_feeds > .postbox-header{
+
+#feedzy_import_feeds>.postbox-header {
display: none;
}
-.post-type-feedzy_imports:not(.edit-php) .page-title-action, .post-type-feedzy_imports:not(.edit-php) .wp-heading-inline {
+
+.post-type-feedzy_imports:not(.edit-php) .page-title-action,
+.post-type-feedzy_imports:not(.edit-php) .wp-heading-inline {
display: none !important;
}
-.post-type-feedzy_imports:not(.edit-php) #wpcontent{
+
+.post-type-feedzy_imports:not(.edit-php) #wpcontent {
padding-left: 0;
}
-.post-type-feedzy_imports:not(.edit-php) #post-body-content{
+
+.post-type-feedzy_imports:not(.edit-php) #post-body-content {
display: none;
}
-.post-type-feedzy_imports:not(.edit-php) .wrap{
+
+.post-type-feedzy_imports:not(.edit-php) .wrap {
margin-top: 0;
margin-right: 0;
}
-.post-type-feedzy_imports:not(.edit-php) .wrap > .wp-heading-inline,
-.post-type-feedzy_imports:not(.edit-php) .wrap > .wp-header-end{
+
+.post-type-feedzy_imports:not(.edit-php) .wrap>.wp-heading-inline,
+.post-type-feedzy_imports:not(.edit-php) .wrap>.wp-header-end {
display: none;
}
-.post-type-feedzy_imports:not(.edit-php) #poststuff{
+
+.post-type-feedzy_imports:not(.edit-php) #poststuff {
padding-top: 0;
}
-.post-type-feedzy_imports:not(.edit-php) #poststuff .inside{
+
+.post-type-feedzy_imports:not(.edit-php) #poststuff .inside {
margin-top: 0;
padding-left: 0;
padding-right: 0;
}
-.post-type-feedzy_imports:not(.edit-php) #poststuff #post-body.columns-2{
+
+.post-type-feedzy_imports:not(.edit-php) #poststuff #post-body.columns-2 {
margin-right: 0;
}
-.post-type-feedzy_imports:not(.edit-php) #post-body.columns-2 #postbox-container-1{
+
+.post-type-feedzy_imports:not(.edit-php) #post-body.columns-2 #postbox-container-1 {
width: 100%;
float: none;
}
+
.feedzy_page_feedzy-settings #wpcontent,
.feedzy_page_feedzy-support #wpcontent,
-.feedzy_page_feedzy-integration #wpcontent{
+.feedzy_page_feedzy-integration #wpcontent {
padding-left: 0;
}
+
.feedzy_page_feedzy-settings .feedzy-header,
.feedzy_page_feedzy-support .feedzy-header,
-.feedzy_page_feedzy-integration .feedzy-header{
+.feedzy_page_feedzy-integration .feedzy-header {
margin-bottom: 40px;
}
@@ -68,7 +81,7 @@
color: #ff0000;
}
-tr.feedzy-import-status-row > td {
+tr.feedzy-import-status-row>td {
margin: 0;
padding: 0
}
@@ -140,47 +153,60 @@ td.feedzy-has-popup {
.feedzy-onboarding-modal {
max-width: 350px;
}
+
.feedzy-onboarding-modal .components-modal__header {
text-align: center;
}
+
.feedzy-onboarding-modal .components-modal__header h1 {
width: 100%;
}
+
.feedzy-onboarding-modal .feedzy-onboarding-modal-content {
text-align: center;
margin: 10px 0 15px;
}
+
.feedzy-onboarding-modal .feedzy-onboarding-modal-action {
text-align: center;
margin: 10px 0;
}
+
.feedzy-onboarding-modal .feedzy-onboarding-modal-action .components-button {
padding: 2px 20px;
font-size: 14px;
margin-right: 10px;
}
+
.components-modal__screen-overlay {
background-color: rgba(0, 0, 0, 0.5);
}
+
.react-joyride__tooltip {
font-size: 13px !important;
}
-.react-joyride__tooltip > div {
+
+.react-joyride__tooltip>div {
text-align: left !important;
}
-.react-joyride__tooltip div:nth-of-type( 2) {
+
+.react-joyride__tooltip div:nth-of-type(2) {
margin-top: 5px !important;
}
+
.react-joyride__tooltip button {
text-decoration: underline;
}
+
.react-joyride__beacon span:first-child {
background-color: #4268CF !important;
}
+
.react-joyride__beacon span:last-child {
background-color: rgba(66, 104, 207, 0.4) !important;
border: 2px solid #4268CF !important;
}
+
.react-joyride__tooltip button[data-action="primary"] {
background: #4268cf !important;
border-color: #006a95 #00648c #00648c !important;
@@ -193,20 +219,25 @@ td.feedzy-has-popup {
line-height: 28px !important;
font-size: 14px !important;
}
+
.react-joyride__tooltip button[data-action="back"] {
color: #23282d !important;
font-size: 14px !important;
}
+
.react-notification-root .notification-container-bottom-left {
bottom: 40px;
}
+
.react-notification-root .notification-container-mobile-bottom {
bottom: 60px;
}
+
.feedzy-onboarding-modal-action .components-button.is-primary,
.feedzy-onboarding-modal-action .components-button.is-primary:hover:not(:disabled) {
background: #4268cf;
}
+
.feedzy-onboarding-modal-action .components-button.is-secondary,
.feedzy-onboarding-modal-action .components-button.is-secondary:hover:not(:disabled),
.feedzy-onboarding-modal-action .components-button.is-tertiary:hover:not(:disabled) {
@@ -279,6 +310,11 @@ i.mce-i-feedzy-icon {
text-align: center;
}
+/* NOTE: It will also exclude the Black Friday notice. */
+.notice:not(.fz-notice):not(.themeisle-sale) {
+ display: none;
+}
+
@media screen and (max-width: 782px) {
tr.feedzy-import-status-row table {
width: 100%;
diff --git a/css/settings.css b/css/settings.css
index 10d681fe..7dbdfcda 100644
--- a/css/settings.css
+++ b/css/settings.css
@@ -270,8 +270,10 @@
border-bottom: 0;
}
.fz-form-wrap .form-label{
- display: block;
+ display: flex;
margin-bottom: 8px;
+ align-items: center;
+ gap: 10px;
}
.fz-form-wrap .form-control {
@@ -558,11 +560,40 @@ fieldset[disabled] .form-control {
}
.fz-form-wrap .chosen-container .chosen-results li{
padding: 8px;
- font-weight: 500;
+ font-weight: 600;
font-size: 16px;
line-height: 19px;
color: #050505;
}
+.fz-form-wrap .chosen-container .chosen-results li.group-result{
+ font-weight: normal;
+ text-transform: uppercase;
+ color: #000000bd;
+ pointer-events: none;
+}
+.fz-form-wrap .chosen-container .chosen-results li.feedzy-pro-terms{
+ pointer-events: none;
+ font-weight: 500;
+}
+.fz-form-wrap .chosen-container .chosen-results li.feedzy-separator{
+ font-size: 0;
+ padding: 0;
+ border-bottom: 1px solid #757575;
+ height: 0;
+}
+.fz-form-wrap .chosen-container .chosen-results li.feedzy-pro-term{
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ color: #757575;
+ pointer-events: none;
+}
+.fz-form-wrap .chosen-container .chosen-results li.feedzy-pro-term .pro-label{
+ background: #80a2ff;
+ padding-left: 7px;
+ padding-right: 7px;
+ border-radius: 5px;
+}
.fz-form-wrap .chosen-container .chosen-results li:hover,
.fz-form-wrap .chosen-container .chosen-results li.result-selected{
background: #F2F2F2;
@@ -1864,10 +1895,12 @@ span.error-message .components-external-link .components-visually-hidden{
border-radius: 8px;
}
.popover-action-list ul{
+ display: flex;
+ flex-direction: column;
+ gap: 14px;
margin: 0;
}
.popover-action-list ul li{
- padding-bottom: 13px;
margin-bottom: 0;
font-size: 16px;
font-weight: 400;
@@ -2179,6 +2212,7 @@ li.draggable-item .components-panel__body-toggle.components-button{
}
.popover-action-list ul li.fz-action-disabled {
cursor: not-allowed !important;
+ color: #757575;
}
.fz-action-panel .fz-chat-cpt-action .fz-notice-wrap,
@@ -2559,6 +2593,32 @@ li.draggable-item .components-panel__body-toggle.components-button{
border-bottom: 0;
padding: 24px 0 0;
}
+.fz-fallback-images {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 1em;
+ margin: 1em 0 1em;
+}
+.feedzy-wrap .fz-spacing{
+ margin: 1em 0 1em;
+}
+.fz-radio-label {
+ font-weight: 600;
+ color: #333;
+ margin-bottom: 4px;
+}
+.fz-radio-description {
+ color: #666;
+ font-size: 13px;
+ line-height: 1.4;
+ display: block;
+}
+.fz-radio-title {
+ font-size: 16px;
+ font-weight: 600;
+ color: #050505;
+}
+
@-webkit-keyframes spin {
100% { -webkit-transform: rotate(360deg); }
}
@@ -2573,4 +2633,44 @@ li.draggable-item .components-panel__body-toggle.components-button{
.support-box-list > ul{
grid-template-columns: repeat(2, 1fr);
}
+}
+
+.fz-license-badge {
+ padding: 2px 8px;
+ font-size: 10px;
+ text-transform: uppercase;
+ border-radius: 5px;
+ letter-spacing: 0.5px;
+ color: #ffffff;
+ background: linear-gradient(135deg, #4268CF 0%, #3458BC 100%);
+}
+
+.feedzy-helper-notice {
+ margin: 15px 0;
+ padding: 16px;
+ background: #e8f4fd;
+ border-left: 4px solid #2271b1;
+ font-size: 14px;
+}
+
+.feedzy-helper-notice p {
+ font-size: 14px;
+}
+
+.feedzy-helper-notice__title {
+ color: #0073aa;
+ font-weight: 600;
+ font-size: 16px;
+ margin-bottom: 8px;
+}
+
+button.feedzy-action-button {
+ padding: 0;
+ font-size: 16px;
+ font-weight: 400;
+ background: none;
+ border: none;
+ width: 100%;
+ cursor: pointer;
+ height: unset;
}
\ No newline at end of file
diff --git a/includes/abstract/feedzy-rss-feeds-admin-abstract.php b/includes/abstract/feedzy-rss-feeds-admin-abstract.php
index 65ff80f1..0027ae1e 100644
--- a/includes/abstract/feedzy-rss-feeds-admin-abstract.php
+++ b/includes/abstract/feedzy-rss-feeds-admin-abstract.php
@@ -620,6 +620,8 @@ public function get_short_code_attributes( $atts ) {
'default' => '',
// thumbs pixel size.
'size' => '',
+ // default aspect ratio for the image.
+ 'aspectRatio' => '1',
// only display item if title contains specific keywords (Use comma(,) and plus(+) keyword).
'keywords_title' => '',
// only display item if title OR content contains specific keywords (Use comma(,) and plus(+) keyword).
@@ -1404,44 +1406,54 @@ private function get_feed_item_filter( $sc, $sizes, $item, $feed_url, $index, $i
$item_link = $item->get_feed()->get_permalink();
}
}
- $new_link = apply_filters( 'feedzy_item_url_filter', $item_link, $sc, $item );
+ $new_link = apply_filters( 'feedzy_item_url_filter', $item_link, $sc, $item );
+ $amp_running = function_exists( 'amp_is_request' ) && amp_is_request();
+ $content_thumb = '';
- // Fetch image thumbnail.
+ $thumbnail_to_use = '';
if ( 'yes' === $sc['thumb'] || 'auto' === $sc['thumb'] ) {
- $the_thumbnail = $this->feedzy_retrieve_image( $item, $sc );
- $content_thumb = '';
+ // Fetch image thumbnail.
+ $thumbnail_to_use = $this->feedzy_retrieve_image( $item, $sc );
+ $thumbnail_to_use = $this->feedzy_image_encode( $thumbnail_to_use );
+
+ if ( empty( $thumbnail_to_use ) && 'yes' === $sc['thumb'] ) {
+ $thumbnail_to_use = $sc['default'];
+ }
+ } else {
+ $thumbnail_to_use = $sc['default'];
+ }
+
+ if ( ! empty( $thumbnail_to_use ) && is_string( $thumbnail_to_use ) ) {
+ $img_style = '';
+
+ if ( isset( $sizes['height'] ) && is_numeric( $sizes['height'] ) ) {
+ $img_style .= 'height:' . $sizes['height'] . 'px;';
+ }
+
+ if ( isset( $sc['aspectRatio'] ) && '1' !== $sc['aspectRatio'] ) {
+ $img_style .= 'aspect-ratio:' . $sc['aspectRatio'] . '; object-fit: fill;';
+ }
+
if (
- is_string( $the_thumbnail ) && ! empty( $the_thumbnail ) &&
+ isset( $sizes['width'] ) && is_numeric( $sizes['width'] ) &&
(
- 'yes' === $sc['thumb'] ||
+ $sizes['width'] !== $sizes['height'] || // Note: Custom modification via filters.
(
- 'auto' === $sc['thumb'] &&
- ! strpos( $the_thumbnail, 'img/feedzy.svg' )
+ isset( $sc['aspectRatio'] ) &&
+ (
+ ( 'auto' === $sc['aspectRatio'] && $amp_running ) || // Note: AMP compatibility. Auto without `height` breaks the layout.
+ '1' === $sc['aspectRatio'] // Note: Backward compatiblity.
+ )
)
)
) {
- $the_thumbnail = $this->feedzy_image_encode( $the_thumbnail );
- $content_thumb .= '';
- if ( ! isset( $sc['amp'] ) || 'no' !== $sc['amp'] ) {
- $content_thumb .= '';
- }
+ $img_style .= 'width:' . $sizes['width'] . 'px;';
}
- if ( empty( $the_thumbnail ) && 'yes' === $sc['thumb'] ) {
- $content_thumb .= '';
- if ( ! isset( $sc['amp'] ) || 'no' !== $sc['amp'] ) {
- $content_thumb .= '';
- }
- }
- $content_thumb = apply_filters( 'feedzy_thumb_output', $content_thumb, $feed_url, $sizes, $item );
- } else {
- $content_thumb = '';
- $content_thumb .= '';
- if ( ! isset( $sc['amp'] ) || 'no' !== $sc['amp'] ) {
- $content_thumb .= '';
- }
- $content_thumb = apply_filters( 'feedzy_thumb_output', $content_thumb, $feed_url, $sizes, $item );
+ $content_thumb .= '
';
+ $content_thumb = apply_filters( 'feedzy_thumb_output', $content_thumb, $feed_url, $sizes, $item );
}
+
$content_title = html_entity_decode( $item->get_title(), ENT_QUOTES, 'UTF-8' );
if ( is_numeric( $sc['title'] ) ) {
$length = intval( $sc['title'] );
@@ -1593,11 +1605,22 @@ private function get_feed_item_filter( $sc, $sizes, $item, $feed_url, $index, $i
if ( empty( $item_content ) ) {
$item_content = esc_html__( 'Post Content', 'feedzy-rss-feeds' );
}
+
+ $img_style = '';
+ if ( isset( $sizes['height'] ) ) {
+ $img_style = 'height:' . $sizes['height'] . 'px;';
+ if ( isset( $sc['aspectRatio'] ) && '1' !== $sc['aspectRatio'] ) {
+ $img_style .= 'aspect-ratio:' . $sc['aspectRatio'] . ';';
+ } elseif ( isset( $sizes['width'] ) ) {
+ $img_style .= 'width:' . $sizes['width'] . 'px;';
+ }
+ }
+
$item_array = array(
'feed_url' => $item->get_feed()->subscribe_url(),
'item_unique_hash' => wp_hash( $item->get_permalink() ),
'item_img_class' => 'rss_image',
- 'item_img_style' => 'width:' . $sizes['width'] . 'px; height:' . $sizes['height'] . 'px;',
+ 'item_img_style' => $img_style,
'item_url' => $new_link,
'item_url_target' => $sc['target'],
'item_url_follow' => isset( $sc['follow'] ) && 'yes' === $sc['follow'] ? 'nofollow' : '',
diff --git a/includes/admin/feedzy-rss-feeds-actions.php b/includes/admin/feedzy-rss-feeds-actions.php
index ffd130ec..e7bb7815 100644
--- a/includes/admin/feedzy-rss-feeds-actions.php
+++ b/includes/admin/feedzy-rss-feeds-actions.php
@@ -493,13 +493,25 @@ private function chat_gpt_rewrite() {
$content = wp_strip_all_tags( $content );
$content = substr( $content, 0, apply_filters( 'feedzy_chat_gpt_content_limit', 3000 ) );
$prompt_content = $this->current_job->data->ChatGPT;
- $ai_provider = 'openai';
+
+ $additional_data = array(
+ 'ai_provider' => 'openai',
+ );
+
if ( isset( $this->current_job->data ) && isset( $this->current_job->data->aiProvider ) ) {
- $ai_provider = $this->current_job->data->aiProvider;
+ $additional_data['ai_provider'] = $this->current_job->data->aiProvider;
}
+
+ if (
+ 'openai' === $additional_data['ai_provider'] &&
+ isset( $this->current_job->data ) && isset( $this->current_job->data->aiModel )
+ ) {
+ $additional_data['ai_model'] = $this->current_job->data->aiModel;
+ }
+
$content = str_replace( array( '{content}' ), array( $content ), $prompt_content );
$openai = new \Feedzy_Rss_Feeds_Pro_Openai();
- $rewrite_content = $openai->call_api( $this->settings, $content, '', array( 'ai_provider' => $ai_provider ) );
+ $rewrite_content = $openai->call_api( $this->settings, $content, '', $additional_data );
// Replace prompt content string for specific cases.
$rewrite_content = str_replace( explode( '{content}', $prompt_content ), '', trim( $rewrite_content, '"' ) );
return $rewrite_content;
diff --git a/includes/admin/feedzy-rss-feeds-admin.php b/includes/admin/feedzy-rss-feeds-admin.php
index dcf45580..d6be8d7b 100644
--- a/includes/admin/feedzy-rss-feeds-admin.php
+++ b/includes/admin/feedzy-rss-feeds-admin.php
@@ -128,6 +128,34 @@ public function enqueue_styles() {
}
wp_register_style( $this->plugin_name, FEEDZY_ABSURL . 'css/feedzy-rss-feeds.css', array(), $this->version, 'all' );
}
+
+ /**
+ * Helper function to enqueue the license script with localization
+ *
+ * @access public
+ * @return void
+ */
+ private function enqueue_license_script() {
+ wp_enqueue_script(
+ $this->plugin_name . '_license',
+ FEEDZY_ABSURL . 'js/feedzy-license.js',
+ array( 'jquery' ),
+ $this->version,
+ true
+ );
+
+ wp_localize_script(
+ $this->plugin_name . '_license',
+ 'feedzyLicense',
+ array(
+ 'l10n' => array(
+ 'licenseKey' => __( 'License Key', 'feedzy-rss-feeds' ),
+ 'checkBtn' => __( 'Check License', 'feedzy-rss-feeds' ),
+ 'errorMsg' => __( 'An error occurred while checking the license. Please try again.', 'feedzy-rss-feeds' ),
+ ),
+ )
+ );
+ }
/**
* Register the stylesheets for the admin area.
@@ -206,6 +234,8 @@ public function enqueue_styles_admin() {
),
)
);
+
+ $this->enqueue_license_script();
}
$upsell_screens = array( 'feedzy-rss_page_feedzy-settings', 'feedzy-rss_page_feedzy-admin-menu-pro-upsell' );
@@ -214,16 +244,39 @@ public function enqueue_styles_admin() {
$asset_file = include FEEDZY_ABSPATH . '/build/action-popup/index.asset.php';
wp_enqueue_script( $this->plugin_name . '_action_popup', FEEDZY_ABSURL . 'build/action-popup/index.js', array_merge( $asset_file['dependencies'], array( 'wp-editor', 'wp-api' ) ), $asset_file['version'], true );
+ $openai_model = '';
+ $open_router_model = '';
+ $integration_settings = get_option( 'feedzy-rss-feeds-settings', array() );
+
+ $all_open_ai_models = apply_filters( 'feedzy_openai_models', array() );
+ $deprecated_open_ai_models = apply_filters( 'feedzy_openai_deprecated_models', array() );
+ $active_open_ai_models = array_values( array_diff( $all_open_ai_models, $deprecated_open_ai_models ) );
+
+ if ( ! empty( $integration_settings['openai_api_model'] ) ) {
+ $openai_model = $integration_settings['openai_api_model'];
+ }
+
+ if ( ! empty( $integration_settings['openrouter_api_model'] ) ) {
+ $open_router_model = $integration_settings['openrouter_api_model'];
+ }
+
wp_localize_script(
$this->plugin_name . '_action_popup',
'feedzyData',
array(
- 'isPro' => feedzy_is_pro(),
- 'isBusinessPlan' => apply_filters( 'feedzy_is_license_of_type', false, 'business' ),
- 'isAgencyPlan' => apply_filters( 'feedzy_is_license_of_type', false, 'agency' ),
- 'apiLicenseStatus' => $this->api_license_status(),
- 'isHighPrivileges' => current_user_can( 'manage_options' ),
- 'languageList' => $this->get_lang_list(),
+ 'isPro' => feedzy_is_pro(),
+ 'isBusinessPlan' => apply_filters( 'feedzy_is_license_of_type', false, 'business' ),
+ 'isAgencyPlan' => apply_filters( 'feedzy_is_license_of_type', false, 'agency' ),
+ 'apiLicenseStatus' => $this->api_license_status(),
+ 'isHighPrivileges' => current_user_can( 'manage_options' ),
+ 'languageList' => $this->get_lang_list(),
+ 'integrationSettings' => get_option( 'feedzy-rss-feeds-settings' ),
+ 'integrations' => array(
+ 'openAIModel' => $openai_model,
+ 'openRouterModel' => $open_router_model,
+ ),
+ 'activeOpenAIModels' => $active_open_ai_models,
+ 'deprecatedOpenAIModels' => $deprecated_open_ai_models,
)
);
@@ -278,8 +331,15 @@ public function enqueue_styles_admin() {
}
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
- if ( 'feedzy_page_feedzy-support' === $screen->base && ( ( isset( $_GET['tab'] ) && 'improve' === $_GET['tab'] ) || ( 'edit' !== $screen->base && 'feedzy_imports' === $screen->post_type ) ) ) {
-
+ $tab = isset( $_GET['tab'] ) ? sanitize_text_field( wp_unslash( $_GET['tab'] ) ) : '';
+
+ if ( 'feedzy_page_feedzy-support' === $screen->base &&
+ (
+ ( 'improve' === $tab )
+ || ( 'edit' !== $screen->base && 'feedzy_imports' === $screen->post_type )
+ || ( 'license' === $tab )
+ )
+ ) {
$asset_file = include FEEDZY_ABSPATH . '/build/feedback/index.asset.php';
wp_enqueue_script( $this->plugin_name . '_feedback', FEEDZY_ABSURL . 'build/feedback/index.js', array_merge( $asset_file['dependencies'], array( 'wp-editor', 'wp-api', 'lodash' ) ), $asset_file['version'], true );
wp_enqueue_style( 'wp-block-editor' );
@@ -293,6 +353,8 @@ public function enqueue_styles_admin() {
)
);
+ $this->enqueue_license_script();
+
wp_set_script_translations( $this->plugin_name . '_feedback', 'feedzy-rss-feeds' );
}
@@ -426,7 +488,7 @@ function closeModal(e) {